Django模型:manytomany有多个对象

时间:2012-06-06 20:41:58

标签: django django-models

我有一个活动模型。活动可以有很多“主持人”。但每个演示者可以使用2种不同类型的配置文件中的一种。 Profile1和Profile2。如何允许两个配置文件进入演示者?

这将是100%后端产生的。至于说,管理员将选择“演示者”。 (不知道这是否重要)。

class Profile1(models.Model):
    user = models.ForeignKey(User, null=True, unique=True)
    first_name = models.CharField(max_length=20, null=True, blank=True)
    last_name = models.CharField(max_length=20, null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    about = models.TextField(null=True, blank=True)
    tags = models.ManyToManyField(Tag, null=True, blank=True)
    country = CountryField()
    avatar = models.ImageField(upload_to='avatars/users/', null=True, blank=True)
    score = models.FloatField(default=0.0, null=False, blank=True)
    organization = models.CharField(max_length=2, choices=organizations)

class Profile2(models.Model):
    user = models.ForeignKey(User, null=True, unique=True)
    first_name = models.CharField(max_length=20, null=True, blank=True)
    last_name = models.CharField(max_length=20, null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    modified = models.DateTimeField(auto_now=True)
    about = models.TextField(null=True, blank=True)
    tags = models.ManyToManyField(Tag, null=True, blank=True)
    country = CountryField()
    avatar = models.ImageField(upload_to='avatars/users/', null=True, blank=True)
    score = models.FloatField(default=0.0, null=False, blank=True)

...

class Event(models.Model):
    title = models.CharField(max_length=200)
    sub_heading = models.CharField(max_length=200)
    presenters = ManyToManyField(Profile1, Profile2, blank=True, null=True)  ?
    ...
    # I've also tried: 
    profile1_presenters = models.ManyToManyField(Profile1, null=True, blank=True)
    profile2_presenters = models.ManyToManyField(Profile2, null=True, blank=True)
    # is there a better way to accomplish this?...

1 个答案:

答案 0 :(得分:3)

我认为你这里有一个设计问题。在我看来,你必须考虑什么是Presenter,以及Presenter与“profile 1”和“profile 2”之间有什么不同。你打算用这个型号做什么?你确定只有两个配置文件吗?从现在开始的某个时间段,是否有可能出现不同的个人资料(“个人资料3”)?和简介4?和简介N?

我建议你再考虑一下你的模特及其关系。不要让这个决定考虑从django admin处理这些模型的难度和容易程度。这是另一个问题,我敢打赌,如果你认为你的模型有点,这将不会成为一个问题。

尽管如此,我可以给你一些关于如何完成你想要的建议(或者我希望如此)。一旦你想到如何建模这些关系,就开始思考你将如何在django中编写模型。以下是您必须回答的一些问题:

每个配置文件是否需要一个不同的表(如果您要使用SQL)? 如果您无法回答,请尝试回答以下问题: 1)两个不同的配置文件有什么区别? 2)是否有多​​个配置文件? 3)每个演示者只有一个配置文件?这个房产在不久的将来会有什么变化?

我不太了解你需要什么,但我认为最好的选择是将你的“Presenter”模型与“Profile”分开。可能是这样的:

class Profile(models.Model):
    first_profile_field = ...
    second_profile_field = ...

# Each presenter have one profile. One profile can "represent" 
# to none or more presenters
class Presenter(models.Model):
    first_presenter_field = ....
    second_presenter_field = ....
    profile = models.ForeignKey(Profile)


class Event(models.Model):
    presenters = models.ManyToManyField(Presenter)
    ....

这只是我想象你可以设计模型的想法。以下是一些链接,可以帮助您正确设计模型并回答我向您提出的问题:

https://docs.djangoproject.com/en/dev/topics/db/models/#model-inheritance

https://docs.djangoproject.com/en/dev/misc/design-philosophies/#models

http://www.martinfowler.com/eaaCatalog/activeRecord.html

在您决定设计的方式后,与管理员合作:

https://docs.djangoproject.com/en/dev/ref/contrib/admin/

修改 如果我没有错,配置文件1和2字段之间的唯一区别是“组织”字段。我对吗?因此,我建议您合并两个模型,因为它们几乎相同。如果他们有不同的方法,或者您想添加不同的经理或其他什么,您可以使用proxy option django模型。例如,您可以这样做:

class Profile(models.Model):
    #All the fields you listed above, including the "organization" field


class GoldenProfile(models.Model):
    #you can define its own managers
    objects = GoldenProfileManager()
    ....
    class Meta:
        proxy = True

class SilverProfile(models.Model):
    ....
    class Meta:
        proxy = True

这样,您可以在每个模型中使用不同的行为定义不同的方法或相同的方法。你可以给他们自己的经理等等。

事件类应保持这样:

class Event(models.Model):
    title = models.CharField(max_length=200)
    sub_heading = models.CharField(max_length=200)
    presenters = ManyToManyField(Profile, blank=True, null=True)

希望它有所帮助!