Django 1.5: Accessing custom user model fields in models.py

吃可爱长大的小学妹 提交于 2019-12-05 06:47:51

Easy one, I think. I have had so many problems with recursive inclusions and so on... Well, the simplest thing to do, when you add a ForeignKey, is to write it like so:

user = models.ForeignKey(settings.AUTH_USER_MODEL, null=False, on_delete=models.CASCADE, verbose_name=_(u"User"))

If you use get_user_model, do not use it like you do. Calling

User = get_user_model()

at the top of the module will try to import your User model, which may, indeed, not have been "installed". Instead, you have several choices:

  • At the top of your module, write

    User = get_user_model # then, you will have to use User() instead of User

  • Write get_user_model() everywhere it's useful. Always in methods or functions, never directly in a model module body.

I had the same problem just now and here is my 2 cents/solution.

If you want to use custom user model in models.py you'll be using for foreign keys settings.AUTH_USER_MODEL and for model methods you have to use get_user_model() but it has to be inside the method. It won't work outside because of circular import.

from django.conf import settings
from django.contrib.auth import get_user_model

class Event(models.Model):

    recipient = models.ForeignKey(settings.AUTH_USER_MODEL)
    ...

    def get_something(self):

        User = get_user_model()
        u = User.objects.get(id=...)
        ...

Make sure your custom User model is not abstract.

I think this import from SomeApp makes a circular import. That's why there is a statement in docs to do something like ForeignKey with calling settings attribute.

As for me, I have encountered with this thing when I used django-filer app. There was a commit on github to prevent imports with get_user_model(). You can use the code there like an example to fix the problem.

This problem is very tricky, because when you try to call get_user_model() from shell - it would work.

The Django documentation has the answer: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.get_user_model

The most relevant section: Generally speaking, you should reference the User model with the AUTH_USER_MODEL setting in code that is executed at import time. get_user_model() only works once Django has imported all models.

The real solution is to make sure that you only use get_user_model() inside of a method, so that it won't get executed at import time.

You have to set,

AUTH_USER_MODEL = "yourapp.CustomUser"

in the settings.py. Then the get_user_model() will work. There is a clean documentation available.

I'm starting to think a workaround might be in order - any comments on the following in SomeApp/models.py:

from django.contrib.auth.models import User as UserModel
try:
    from django.contrib.auth import get_user_model
except ImportError:  #django <= 1.4 doesn't have get_user_model so define our own
    def get_user_model():
        return UserModel
User = getattr(settings, 'AUTH_USER_MODEL', 'auth.User')
...
def SomeModel(models.Model):
    user = models.ForeignKey(User)  # using the name of the model
    def some_method(self, email):
        qs = get_user_model().objects.filter(email=email)  # using function call to get model class 

Are you running South 0.8.3?

Ensure that you running South at least 0.8.4

GitHub issue South Release Notes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!