Django ManyToMany怀疑

时间:2011-07-16 22:20:47

标签: python django django-orm

我有这个型号:

class Comment(models.Model):
    text = models.TextField(max_length = 300)
    author = models.ForeignKey(User)
    timestamp = models.DateTimeField(auto_now_add = True)

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique = True)
    comments = models.ManyToManyField(Comment)

class Product(models.Model):
    title = models.CharField(max_length = 30)
    comments = models.ManyToManyField(Comment)

我知道有django.contrib.comments但现在我正在编写自己的评论系统。

UserProfile和Product对象都可以包含注释列表。 这在逻辑上是正确的吗?

我的疑问是: ManyToManyField 表示:

  • 对象A具有许多对象B,因此对象B具有许多对象A
  • 或许多物体A有许多物体B?

哪一个是正确的句子?因为如果它是第一个,我的模型布局是错误的,因为(例如)产品有很多评论,但评论的产品不多。

你能澄清我的疑问吗?

1 个答案:

答案 0 :(得分:1)

你的第一个陈述是正确的,对于 ManyToManyField “一个对象A有很多对象B,所以对象B有很多对象A”

请注意,当您定义

class Comment(models.Model):
    text = models.TextField(max_length = 300)
    author = models.ForeignKey(User)
    timestamp = models.DateTimeField(auto_now_add = True)

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique = True)
    comments = models.ManyToManyField(Comment)

在UserProfile的Comment上定义了一种隐式的ManyToManyField,例如

class Comment(models.Model):
    text = models.TextField(max_length = 300)
    author = models.ForeignKey(User)
    timestamp = models.DateTimeField(auto_now_add = True)
    userprofiles = models.ManyToManyField(UserProfile)

class UserProfile(models.Model):
    user = models.ForeignKey(User, unique = True)

事实上,你可以在任何一种方式定义多对多的表。

正如您所知,您的模型定义不适用于两个 ManyToManyFields 。您想要使用的是GenericForeignKey,它可以将任何内容附加到其他任何内容上(这就是评论框架如何工作IIRC)。

这样的东西
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Comment(models.Model):
    text = models.TextField(max_length = 300)
    author = models.ForeignKey(User)
    timestamp = models.DateTimeField(auto_now_add = True)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')