你”重新寻找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