2009-12-01 54 views
22

Tôi có một mô hình được định nghĩa như thế này:đối tượng 'RelatedManager' không có thuộc tính

class UserDetail(models.Model): 
    user = models.ForeignKey(User, db_index=True, unique=True, related_name='details') 
    favourites = models.ManyToManyField(Article, related_name='favourited_by', blank=True) 

Và tôi đang cố gắng để làm một cái gì đó như thế này:

article = get_object_or_404(Article, pk=id) 
request.user.details.favourites.add(article) 

Tại sao không cho nó hoạt động?

Tôi nhận được lỗi này:

'RelatedManager' object has no attribute 'favourites'

Tôi đoán details không phải là loại đúng, nhưng tại sao không phải là nó? Và làm cách nào tôi có thể thực hiện một truy vấn như vậy?

Trả lời

36

Khi bạn truy cập user.details, nó truy cập vào phần sau của khóa ngoài UserDetail.user. Bản thân Khóa ngoài không chỉ định rằng User chỉ có thể có một UserDetail, vì vậy django cung cấp cho bạn RelatedManager, bạn có thể lọc và truy vấn giống như thông thường Manager. Vì vậy, bạn làm những việc tương tự với nó mà bạn làm với các nhà quản lý .objects của bạn. Bạn có thể yêu cầu user.details.all(), user.details.filter(), user.details.get(), v.v. sẽ cung cấp cho bạn một queryset, một đối tượng hoặc một ngoại lệ, tùy thuộc vào phương pháp và kết quả.

+1

Oh! Điều đó có ý nghĩa hơn nhiều bây giờ. Tôi đoán rõ ràng là * tôi * rằng người dùng chỉ có một 'UserDetail', nhưng tôi cho rằng nó không được chỉ định ở bất cứ đâu. Cảm ơn bạn. – mpen

+8

Nếu bạn thay đổi mô hình của mình để thay vì sử dụng ForeignKey, bạn đã sử dụng OneToOneField, bạn sẽ có thể thực hiện chính xác như bạn mong đợi. OneToOneFields giống như ForeignKeys ngoại trừ vì chúng chỉ là một đối tượng liên quan, Django sẽ cho phép bạn truy cập trực tiếp đối tượng thay vì thông qua một người quản lý liên quan. Xem https://docs.djangoproject.com/en/dev/ref/models/fields/#onetoonefield – mbargiel

8

Hãy thử

request.user.details.get().favourites.add(article) 

này giả định đối tượng UserDetail đã tồn tại cho người dùng đó, nếu không get() sẽ nâng cao một ngoại lệ.

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