你」重新尋找GenericForeignKey,example:
class Vote(models.Model):
class Meta:
db_table = "votes"
index_together = [
["content_type", "object_id"],
]
# The following 3 fields represent the Comment or Post
# on which a vote has been cast
# See Generic Relations in Django's documentation
content_type = models.ForeignKey(ContentType, on_delete=models.PROTECT)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey('content_type', 'object_id')
voter = models.ForeignKey(User, on_delete=models.PROTECT)
type_of_vote = models.IntegerField(choices = (
(UPVOTE, 'Upvote'),
(DOWNVOTE, 'Downvote'),
(FLAG, 'Flag'),
))
submission_time = models.DateTimeField(auto_now_add=True)
這裏,則contentType模型代表和有關安裝在您的項目(相冊,照片,視頻......)的模型存儲信息,而當安裝了新的模型自動創建的ContentType的新實例。
現在我們不需要保留我們想跟蹤的其他Django模型的外鍵。使用GenericRelations,我們現在可以跟蹤我們想要的任何模型的投票,而無需修改投票模型。
反向關係將成爲我們需要跟蹤的模型的一部分。例如:
class Post:
...
...
votes = GenericRelation(Vote)
...
...
class Comment:
...
...
votes = GenericRelation(Vote)
...
...
現在,如果我們把多花點心思我們現有的Post和Comment模型,我們可以觀察到兩種模式的行爲應該或多或少以同樣的方式。例如,他們都可以被提高,降低投票率,被標記,沒有被標記,所以他們應該提供接口來這樣做。
因此,我們可以爲它們創建一個基類並將其推向常見行爲和屬性。郵件和評論將是具體的類,並將繼承Votable。
class Votable(models.Model):
""" An object on which people would want to vote
Post and Comment are concrete classes
"""
class Meta:
abstract = True
votes = GenericRelation(Vote)
author = models.ForeignKey(User, on_delete=models.PROTECT)
# denormalization to save database queries
# flags = count of votes of type "Flag"
upvotes = models.IntegerField(default=0)
downvotes = models.IntegerField(default=0)
flags = models.IntegerField(default=0)
def upvote(self, user):
....
....
def downvote(self, user):
....
....
class Post(Votable):
# post specific implementation
...
...
class Comment(Votable):
# comment specific implementation
...
...
Source
more info
了很多很好的信息和參考這裏。如果我需要分兩次進行分類,會怎麼樣?喜歡,一張照片可以評論和投票? – Jaberwocky
你可以有像上面這樣的抽象類,例如:VotableMixin,CommentableMixin。然後:class Photo(VotableMixin,CommentableMixin) – ziiiro
@ziiro你有沒有另一個好的學習資源呢? – Jaberwocky