Django'喜欢' - ManyToManyField vs new model

时间:2015-09-07 13:42:39

标签: python django django-models

我正在为我的网站在配置文件上实现喜欢,我不确定哪种是最佳做法,像ManyToManyField这样:

class MyUser(AbstractBaseUser):
    ...
    likes = models.ManyToManyField('self', symmetrical = False, null = True)
    ...

或者只是创建一个类就像这样:

class Like(models.Model):
    liker = models.ForeignKey(MyUser, related_name='liker')
    liked = models.ForeignKey(MyUser, related_name='liked')

其中一个比另一个更好吗?如果是这样,为什么?

感谢

4 个答案:

答案 0 :(得分:4)

应优先考虑第一个选项。如果您需要一些其他字段来描述相似内容,您仍然可以在through="Likes"中使用ManyToManyField并定义模型Likes

操纵数据条目也会更加pythonic:

# returns an object collection
likes_for_me = MyUser.objects.filter(pk=1).likes

而不是:

me = MyUser.objects.filter(pk=1)
likes_for_me = Like.objects.filter(liked=me)

答案 1 :(得分:3)

第二个选项基本上是内部完成的:创建一个新表,用于创建实体之间的链接。

对于第一个选项,你让django为你完成这项工作。

选择当然更多是关于如何执行请求。在第二个选项中,您必须查询与您的模型匹配的Like模型,而在第一个选项上,您只需要请求MyUser,您可以从中访问连接。

答案 2 :(得分:2)

第二个选项更灵活,更具扩展性。例如,您可能希望跟踪何时创建(仅添加Like.date_created字段)。此外,您可能希望在喜欢内容时向内容作者发送通知。但最初只是喜欢(添加Like.cancelled boolead字段并用一些逻辑包装它......)。

所以我会选择单独的模型。

答案 3 :(得分:0)

我认为您选择的那个完全取决于您认为更容易实施或更好的那个。我倾向于总是使用第一种方法,因为它更直接和合乎逻辑,至少对我来说。我也不同意 Igor 的观点,因为它不灵活和可扩展,你也可以在它发生时启动通知。如果您打算使用 Django rest 框架,那么我完全建议使用第一种方法,因为第二种方法可能会很痛苦。

class Post(models.Model):
    like = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=True, related_name='post_like')

那么在您看来,您只需这样做。

@api_view(['GET'])
@permission_classes([IsAuthenticated])
def like(request, id):
    signed_in = request.user
    post = Post.objects.get(id=id)

    if signed_in and post:
        post.like.add(signed_in)
        # For unlike, remove instead of add
        return Response("Successful")
    else:
        return Response("Unsuccessful",  status.HTTP_404_NOT_FOUND)

然后您可以在前端随意使用响应。