2013-07-04 33 views
6

Tôi đang làm việc trên dự án Django 1.5 và tôi có một mô hình người dùng tùy chỉnh (hãy gọi nó là CustomUser). Một ứng dụng khác (SomeApp) cần tham khảo mô hình người dùng tùy chỉnh này. Theo mục đích của ForeignKey và như vậy, các tài liệu Django nói để sử dụngDjango 1.5: Truy cập các trường mô hình người dùng tùy chỉnh trong models.py

User = settings.AUTH_USER_MODEL 

Tuy nhiên, một số chức năng trong SomeApp.models cần truy cập vào điều gì sẽ trước đây được biết đến như User.objects. Nhưng người dùng bây giờ là một chuỗi và không phải là một lớp, do đó, User.objects không thành công. Việc thay thế sẽ

from django.contrib.auth import get_user_model 
User = get_user_model() 

Những công trình trong các module khác, nhưng khi tôi sử dụng này trong models.py của SomeApp, Django đặt ra một lỗi:

ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL)

Bất kỳ ý tưởng?

EDIT 1 - Traceback:

Traceback (most recent call last): 
    File "<console>", line 1, in <module> 
    File "...\django-badger\badger\__init__.py", line 7, in <module> 
    from badger.models import Badge, Award, Progress 
    File "...\django-badger\badger\models.py", line 26, in <module> 
    User = get_user_model() 
    File "...\lib\site-packages\django\contrib\auth\__init__.py", line 127, in get_user_model 
    raise ImproperlyConfigured("AUTH_USER_MODEL refers to model '%s' that has not been installed" % settings.AUTH_USER_MODEL) 
ImproperlyConfigured: AUTH_USER_MODEL refers to model 'MyApp.AuthUser' that has not been installed 

EDIT 2 - INSTALLED_APPS cài đặt:

INSTALLED_APPS = (
'django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.sites', 
'django.contrib.messages', 
'django.contrib.staticfiles', 
'django.contrib.admin', 
'django.contrib.admindocs', 
'south', 
'MyApp', # this is where my user model is defined 
'SomeApp', # I try to use get_user_model() in this app's models.py; doesn't work. 
'social_auth', 
) 
+0

Bạn có thể đăng toàn bộ lượt truy cập không? – jpic

+0

Bạn đã xác định 'AUTH_USER_MODEL' như thế nào trong cài đặt của mình? Trong đó ứng dụng là người dùng và tên lớp cho nó là gì? – matino

+0

@matino - vâng, nó được xác định trong cài đặt. get_user_model() hoạt động tốt trong tất cả các tệp khác ngoại trừ models.py. Mô hình người dùng tùy chỉnh AuthUser của tôi được định nghĩa trong MyApp (trong ví dụ này) – askvictor

Trả lời

0

Bạn phải thiết lập,

AUTH_USER_MODEL = "yourapp.CustomUser"

trong settings.py. Sau đó, get_user_model() sẽ hoạt động. Có một số documentation available sạch sẽ.

+0

Đã có. get_user_model() hoạt động trong các tệp khác ngoại trừ models.py. – askvictor

+0

Kiểm tra thứ tự của 'INSTALLED_APPS'. Ứng dụng chứa 'CustomUser' sẽ ở trên cùng nhiều nhất so với các ứng dụng khác. Giải thích chi tiết ở đây, https://code.djangoproject.com/ticket/19218 – Babu

0

Tôi bắt đầu suy nghĩ một cách giải quyết có thể được theo thứ tự - bất kỳ ý kiến ​​trên sau trong 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 
+0

Hey @askvictor, làm cách nào bạn kết thúc việc giải quyết vấn đề này? Tôi đang gặp sự cố tương tự này nhưng trong khi đang chạy di chuyển và trên gói được cài đặt sau ứng dụng của tôi. – tzenderman

+0

@tzenderman - giải quyết nó bằng cách đặt dự án vào trong khi: -/Đối với di chuyển, tôi đã có một số vấn đề liên quan mà tôi đã giải quyết bằng cách tạo ra một di chuyển trung gian cùng với require_by hoặc depends_on: http: // stackoverflow.com/questions/17711515/django-south-circular-dependency – askvictor

3

Hãy chắc chắn rằng mô hình tài khoản tùy chỉnh của bạn không phải là trừu tượng.

1

Tôi cho rằng việc nhập từ SomeApp này thực hiện nhập khẩu vòng tròn. Đó là lý do tại sao có một tuyên bố trong docs để làm một cái gì đó như ForeignKey với thuộc tính cài đặt gọi điện thoại.

Đối với tôi, tôi đã gặp phải điều này khi tôi sử dụng ứng dụng django-filer. Đã có commit trên github để ngăn nhập khẩu bằng get_user_model(). Bạn có thể sử dụng mã ở đó như một ví dụ để khắc phục sự cố.

Vấn đề này rất phức tạp, bởi vì khi bạn cố gắng gọi get_user_model() từ trình bao - nó sẽ hoạt động.

8

Tôi đã gặp sự cố tương tự ngay bây giờ và đây là 2 xu/giải pháp của tôi.

Nếu bạn muốn sử dụng mô hình người dùng tùy chỉnh trong models.py bạn sẽ được sử dụng cho các phím nước ngoài settings.AUTH_USER_MODEL và các phương pháp mô hình mà bạn phải sử dụng get_user_model() nhưng nó phải được bên phương pháp. Nó sẽ không hoạt động bên ngoài vì nhập vòng tròn.

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=...) 
     ... 
+2

Đây là câu trả lời cuối cùng. Cảm ơn Freon! –

10

Dễ dàng, tôi nghĩ vậy. Tôi đã có rất nhiều vấn đề với các tạp chất đệ quy và vân vân ... Vâng, điều đơn giản nhất để làm, khi bạn thêm một ForeignKey, là viết nó như vậy:

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

Nếu bạn sử dụng get_user_model, không sử dụng nó như bạn làm. Gọi số

User = get_user_model() 

ở đầu mô-đun sẽ cố gắng nhập mô hình User của bạn, thực tế, chưa được "cài đặt". Thay vào đó, bạn có nhiều lựa chọn:

  • Ở phía trên của mô-đun của bạn, viết

    User = get_user_model # sau đó, bạn sẽ phải sử dụng tài khoản() thay vì tài

  • Viết get_user_model() ở mọi nơi hữu ích. Luôn luôn trong phương pháp hoặc chức năng, không bao giờ trực tiếp trong một mô hình mô-đun cơ thể.

+0

Điều này làm việc cho tôi. Tôi đã nhập get_user_model() ở phía trên cùng của tệp. Cảm ơn bạn – Howie

+0

Bạn xử lý vấn đề này như thế nào trong mã khai báo? Ví dụ, một lớp UserSerializer có một lớp Meta, nơi mô hình được chỉ định. Bạn không thể trì hoãn định nghĩa Mô hình người dùng thành thời gian thực thi vì toàn bộ định nghĩa được phân tích cú pháp trong thời gian nhập. – dangonfast

0

Bạn có đang chạy South 0.8.3 không?

Đảm bảo rằng bạn chạy Nam ít nhất 0.8.4

GitHub issue Nam phát hành Notes

1

Các tài liệu Django có câu trả lời: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.get_user_model

Phần phù hợp nhất: Nói chung , bạn nên tham khảo mô hình Người dùng bằng cài đặt AUTH_USER_MODEL trong mã được thực hiện tại thời điểm nhập. get_user_model() chỉ hoạt động khi Django đã nhập tất cả các mô hình.

Giải pháp thực tế là đảm bảo rằng bạn chỉ sử dụng get_user_model() bên trong một phương thức để nó không được thực thi tại thời điểm nhập.

Các vấn đề liên quan