0

我有一个事件模型。事件可以有许多“演示者”。但是每个演示者都可以选择 2 种不同类型的个人资料中的一种。配置文件 1 和配置文件 2。如何允许两个配置文件进入演示者?

这将是 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?...
4

1 回答 1

3

我认为你在这里有一个设计问题。在我看来,您必须考虑什么是 Presenter,以及具有“profile 1”和“profile 2”的 Presenter 之间有什么不同。你打算用这些模型做什么?您确定只有两个配置文件吗?从现在开始的某个时间,是否有可能出现不同的配置文件(“配置文件 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 字段之间的唯一区别是“组织”字段。我对吗?因此,我建议您合并这两个模型,因为它们几乎相同。如果他们有不同的方法,或者你想添加不同的管理器或其他什么,你可以使用 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)

希望能帮助到你!

于 2012-06-07T04:13:35.183 回答