问题描述:

I have this models:

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)

I know there's django.contrib.comments but now I'm writing my own comments system.

Either UserProfile and Product object can have a list of comments.

Is it logically correct this?

My doubt is: a ManyToManyField means:

  • an object A has many objects B, so an object B has many objects A
  • or many objects A has many objects B ?

Which one it's the correct sentence? Because if it is the first one, my models layout it's wrong, because (for example) a Product has many Comments but a Comment has NOT many Product.

Can you clarify my doubt?

网友答案:

Your first statement is correct, for a ManyToManyField "an object A has many objects B, so an object B has many objects A"

Note that when you define

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)

There is a kind of implicit ManyToManyField defined on Comment for UserProfile, eg

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)

In fact you can define the many to many table either way round.

As you've noted your model definition doesn't work with two ManyToManyFields. What you want to use is a GenericForeignKey which can attach anything to anything else (which is how the commenting framework works IIRC).

Something like

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')
相关阅读:
Top