20

Tôi đã pored trên các tài liệu Django liên quan đến khung contenttypes nhiều lần, và tôi chỉ đơn giản là không hiểu nó cũng đủ để thực hiện quan hệ chung trong dự án của tôi. Tôi đã tìm kiếm các ví dụ hoặc hướng dẫn trực tuyến về vấn đề này, nhưng tôi không thể tìm thấy một tài liệu duy nhất. Hãy gọi cho tôi câm, nhưng tôi cần một số trợ giúp về điều này (xin vui lòng không trả lời bằng cách đơn giản là liên kết với các tài liệu). Dựa trên việc thiếu tài nguyên trực tuyến, tôi tin rằng nếu bạn trả lời câu hỏi này với một ví dụ kỹ lưỡng, câu trả lời của bạn có thể là ví dụ hữu ích nhất trực tuyến cho đến nay về quan hệ chung của django (tiền thưởng!). Vì vậy, câu hỏi của tôi là: ai đó có thể hiển thị một ví dụ đơn giản về các mô hình và có thể là một vài dòng mã hiển thị cách tương tác với các trường hợp của một mô hình chung không? Không.Django: Ví dụ về các mối quan hệ chung sử dụng khung nội dung?


Là nguồn cảm hứng, đây là những gì tôi tin rằng sẽ là một tình huống rất phổ biến:

Một trang web có mục phương tiện truyền thông được điều trị chủ yếu là giống nhau, nhưng là hơi khác nhau. Ví dụ: giả sử có các mục hình ảnh và video và người dùng có thể "thích" một mục hoặc "nhận xét" trên một mục. Các lượt thích và nhận xét cần được xử lý như nhau, bất kể chúng được đăng trên một mục hình ảnh hay video. Vì vậy, nếu có một ItemView để xem hình ảnh hoặc video trong album của người dùng, có thể thực hiện các loại cuộc gọi sau đây: mediaitem.comments.all() hoặc len(mediaitem.likes.all()) hoặc comment.user_who_commented, mà không cần phải biết loại phương tiện đó là gì (hình ảnh hoặc video) .

Tôi tin rằng bạn sẽ cần sáu mô hình cho việc này:

  • Tóm tắt MediaItem lớp
  • Hai loại khác nhau của mục phương tiện truyền thông: ImageItemVideoItem
  • Tóm tắt MediaItemActions lớp
  • Hai khác nhau các loại hành động có thể được thực hiện đối với các mục phương tiện: LikeComment

Nếu bạn biết làm thế nào để sử dụng tính năng Django này, xin vui lòng cho chúng tôi xem một ví dụ đầy đủ! Tôi cảm thấy như nó sẽ là một công cụ vô cùng mạnh mẽ và đang đau đớn để sử dụng nó trong ứng dụng của tôi. Rõ ràng hơn, càng tốt.

Trả lời

5

Trường hợp sử dụng của bạn có vẻ rất giống với (hiện không được chấp nhận) Django comments framework. Nếu bạn xem models, bạn sẽ thấy cách sử dụng mối quan hệ chung trong BaseCommentAbstractModel - lưu ý rằng bạn cần cả ba trường, ForeignKey đến ContentType, một trường để giữ các đối tượng 'pk s' và trường GenericForeignKey.

Đối với cách truy vấn đối tượng theo GenericForeignKey, bạn có thể xem một số ví dụ trong dự án đó là template tags. Xem ví dụ phương thức get_query_set trong BaseCommentNode, truy xuất nhận xét bằng cách truy vấn về loại nội dung và pk của đối tượng mục tiêu.

def get_query_set(self, context): 
    ctype, object_pk = self.get_target_ctype_pk(context) 
    if not object_pk: 
     return self.comment_model.objects.none() 

    qs = self.comment_model.objects.filter(
     content_type = ctype, 
     object_pk = smart_text(object_pk), 
     site__pk  = settings.SITE_ID, 
    ) 
1

Tùy chọn khác là Polymorphic Models. Tôi sẽ không nói đó là cách bạn nên đi, nhưng nó có lẽ có thể là một lựa chọn.

Tôi là người hâm mộ của cả hai khóa ngoại quốc chung và Mô hình đa hình. Các mô hình đa hình hoạt động tốt nhất trong các kịch bản có nhiều điểm giống nhau trong các mô hình.

3

Tôi thực sự có một tình huống rất giống với một trong các dự án của mình, với nhiều loại phương tiện khác nhau.

class TaggedItem(models.Model): 
    tag = models.SlugField() 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 

class ReviewedItem(models.Model): 
    content_type = models.ForeignKey(ContentType) 
    object_id = models.PositiveIntegerField() 
    content_object = generic.GenericForeignKey('content_type', 'object_id') 
    review = models.ForeignKey("Review") 

class CreativeWork(models.Model): 
    #other fields 
    keywords = generic.GenericRelation("TaggedItem",null=True, blank=True, default=None) 
    reviews = generic.GenericRelation("ReviewedItem",null=True, blank=True, default=None) 

class MediaObject(CreativeWork): 
    #fields 
class VideoObject(MediaObject): 
    #fields 
class AudioObject(MediaObject): 
    #fields 

Mọi video hoặc âm thanh là MediaObject, là CreativeWork. CreativeWorks có GenericRelation cho các thẻ và Bài đánh giá. Vì vậy, bây giờ bất cứ điều gì có thể được gắn thẻ hoặc xem xét.

Tất cả những gì bạn cần là cho 'hành động' để có một ForeignKey thành ContentType. Hơn cả việc thêm GenericRelation vào mô hình của bạn. Tôi thực sự tìm thấy django.docs là khá hữu ích :) Nhưng nếu không hy vọng điều này sẽ giúp.

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