【问题标题】:Django: Are multiple Generic Relations in one Model bad design?Django:一个模型中的多个泛型关系是糟糕的设计吗?
【发布时间】:2013-07-15 07:56:43
【问题描述】:

我有一个具有多个通用关系的模型,在我的模板中使用它变得非常复杂。该模型是在“场地”和/或“音乐节”上举行的“演出”或音乐活动,并具有“音乐家”和/或“合奏团”。

复杂的地方在于,每个“演出”都有一个演示者、发起人和一个代理。这些被设置为与其他模型(例如“PresenterCompany”)的通用关系。演示者公司可以是同一演出的发起人、演示者或代理,或所有这些人。以下是模型(为参考简化):

class Gig(models.Model):
    description = models.CharField(max_length=100, blank=True)
    date = models.DateTimeField()
    venue = models.ForeignKey(Venue)
    festival = models.ForeignKey(Festival, blank = True, null=True)
    musician = models.ManyToManyField(Musician, blank=True)
    ensembles = models.ManyToManyField(Ensemble, blank = True)

    presenter_content_type = models.ForeignKey(ContentType,
        limit_choices_to={"model__in": ("Individual", "ArtsOrganization",'Presenter', "BookingAgent","Festival", "OtherOrganization","PresenterCompany", "Venue")}, related_name = "Presenter Type", verbose_name = "Presenter",blank=True, null=True)
    presenter_id = models.IntegerField(db_index=True, blank=True, null=True, verbose_name='Presenter ID')
    presenter = generic.GenericForeignKey('presenter_content_type','presenter_id')

    promoter_content_type = models.ForeignKey(ContentType,
        limit_choices_to={"model__in": ("Individual", "ArtsOrganization","BookingAgent","Presenter", "Festival", "OtherOrganization","PresenterCompany", "Venue")}, related_name = "promotor", verbose_name='Promoter Type', blank=True, null=True)
    promoter_id = models.IntegerField(db_index=True, blank=True, null=True, verbose_name='Promoter ID')
    promoter = generic.GenericForeignKey('promoter_content_type','promoter_id')

    agent_content_type = models.ForeignKey(ContentType,
        limit_choices_to={"model__in": ("Individual", "BookingAgent")}, related_name="agent", verbose_name='Agent Type', blank=True, null=True)
    agent_id = models.IntegerField(db_index=True, blank=True, null=True, verbose_name='Agent ID')
    agent = generic.GenericForeignKey('agent_content_type','agent_id')


class PresenterCompany(models.Model):
    name = models.CharField(max_length=70)
    address =GenericRelation(Address)
    presented_gig = GenericRelation('Gig',
        content_type_field='presenter_content_type',
        object_id_field='presenter_id',
        related_name='presenter_presented_gig'
    )

    promoted_gig = GenericRelation('Gig',
        content_type_field='promoter_content_type',
        object_id_field='promoter_id',
        related_name='presenter_promoted_gig'
    )
    booked_gig = GenericRelation('Gig',
        content_type_field='promoter_content_type',
        object_id_field='promoter_id',
        related_name='presenter_booked_gig'
    )

主要问题是,当我尝试为演示者公司获取所有演出时,我必须为每个角色编写三个不同的 for 循环,即 {% for gig in presentercompany.presented_gig.all %},依此类推...这似乎是多余的代码。

有没有更好的方法来构建它,例如为演示者、推广者和代理使用中间模型?谢谢你的建议!

【问题讨论】:

    标签: django models generic-relations


    【解决方案1】:

    一般的关系肯定很难处理。我只会在没有其他选择时使用它们。

    在您的情况下,我看到了其他几个选项。您可以在 PresenterCompanyGig 之间建立多对多关系,使用直通表指定关系类型 (https://docs.djangoproject.com/en/2.0/topics/db/models/#extra-fields-on-many-to-many-relationships):

    class Gig(models.Model):
        description = models.CharField(max_length=100, blank=True)
        date = models.DateTimeField()
        venue = models.ForeignKey(Venue)
        festival = models.ForeignKey(Festival, blank=True, null=True)
        musician = models.ManyToManyField(Musician, blank=True)
        ensembles = models.ManyToManyField(Ensemble, blank=True)
    
    
    class PresenterCompanyGigRelationship(models.Model):
        gig = models.ForeignKey(Gig, on_delete=models.CASCADE)
        presenter_company = models.ForeignKey(
            'PresenterCompany', on_delete=models.CASCADE)
        relationship = models.CharField(
            max_length=10,
            choices=(
                ('presenter', 'Presenter'),
                ('promoter', 'Promoter'),
                ('agent', 'Agent'),
                ))
    
    
    class PresenterCompany(models.Model):
        name = models.CharField(max_length=70)
        git = models.ManyToManyField(Gig, through=PresenterCompanyGigRelationship)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-28
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 2011-08-12
      相关资源
      最近更新 更多