我如何使用'通过'在Django ManytoMany关系中?

时间:2017-05-04 13:33:46

标签: django

我已经阅读了文档,但有一件事在使用'通过'时并不清楚。在ManyToMany关系中。

假设我有一个'会议'模特和一个女主角'模型。

'公约'是' Persona'的集合。

'假面'是一种人的代表,但不包含“计数”。不同数量的“人物”#39;可以加入一个或多个“公约”。 - 这就是我需要捕捉的东西。

我怎么说会议A由数量的Persona M和Y的Persona N组成?虽然一个角色代表了一种人,但它并没有给我一个数量的人物角色M'参加公约?这是我需要在中间模型中捕获的额外数据。

也就是说,在设置我的模型时,应该'会议'与一个名为' ConventionPersonas'的表有一个ManytoMany关系。有计数,FK到公约,还有FK到群组?

-OR -

我应该有一个'会议'与' Persona'具有ManyToMany关系的模型通过' ConventionPersona' - 并且仍然允许“人物”#39;在许多不同的公约'?

Models.py

class Convention(models.Model):
    personas = models.ManyToManyField(Persona through='ConventionPersona') #<-- use through here?
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

    def save_convention(self):
        '''
        Set timestamp and save object
        '''
        self.save()

    class Meta:
        ordering = ('name',)

class Persona(models.Model):
    name = models.CharField(max_length=255)
    description = models.CharField(max_length=255)
    attributes = models.ManyToManyField(Attribute)

    def __str__(self):
        return self.name

- 提出新模式......使用&#39;通过&#39;? -

class ConventionPersona(models.Model):
    '''
    A Persona should exist as a descriptor with zero
    count allowing a it to be used with 
    different weights, or counts, for different Conventions.
    '''
    conventionId = models.ForeignKey(Convention)
    personaId = models.ForeignKey(Persona)
    count = models.IntegerField()

    def __str__(self):
        return self.name

3 个答案:

答案 0 :(得分:1)

这一切都取决于你如何保存你的记录。如果您为每个Convention-Persona记录添加新记录,那么您可以执行类似的操作。

class ConventionPersona(models.Model):
    '''
    A Persona should exist as a descriptor with zero
    count allowing a it to be used with 
    different weights, or counts, for different Conventions.
    '''
    conventionId = models.ForeignKey(Convention)
    personaId = models.ForeignKey(Persona)
    count = models.IntegerField()

    def __str__(self):
        return self.name

    def myCount(self):
       p = ConventionPersona.objects.filter(personaId = self.id)
       return len(p)

虽然处理过程很重要

答案 1 :(得分:1)

您并没有真正提供模型的完整结构,但我会假设以下内容:

class Persona(models.Model):
    persona_type = models.CharField(max_length=100)

class Individual(models.Model):
    name = models.CharField(max_length=100)
    # In this example, an Individual can only have one Persona but 
    # a persona could be attached to many Individuals
    persona = models.ForeignKey(Persona)

class Convention(models.Model):
    people = models.ManyToManyField(Individual)

由于ManyToMany字段具有对象管理器,因此您可以通过以下方式获取字符数:

my_convention.people.filter(persona=persona_of_interest).count()

如果您不包括该Persona的所有成员,我不确定您将Persona直接附加到公约的目的是什么;如果这里还有其他要求,请随时澄清。

答案 2 :(得分:1)

我想也许你是在思考这个问题,或者我可能是在思考它,但我相信你会想要用Persona的外键来设置你的Convention模型。这允许您表示许多角色可以属于单一约定的事实

class Persona(models.Model):
    convention = models.ForeignKey(Convention)
    name = models.CharField(max_length=255)
    description = models.CharField(max_length=255)
    attributes = models.ManyToManyField(Attribute)

   def __str__(self):
       return self.name

然后回答你所提出的一个问题:我怎么说会议A由X号的Persona M组成,你可以做到

convention_A = Convention.objects.get(name='A')
perona_m_count = Persona.objects.filter(name='M', convention=convention_A).count()