Django ManyToManyField使用直通订购

Bri*_*ian 22 python django many-to-many

以下是我的模型设置的片段:

class Profile(models.Model):     
    name = models.CharField(max_length=32)

    accout = models.ManyToManyField(
        'project.Account',
        through='project.ProfileAccount'
    )

    def __unicode__(self)
        return self.name

class Accounts(models.Model):
    name = models.CharField(max_length=32)
    type = models.CharField(max_length=32)

    class Meta:
        ordering = ('name',)

    def __unicode__(self)
        return self.name

class ProfileAccounts(models.Model):
    profile = models.ForeignKey('project.Profile')
    account = models.ForeignKey('project.Accounts')

    number = models.PositiveIntegerField()

    class Meta:
        ordering = ('number',)
Run Code Online (Sandbox Code Playgroud)

然后,当我访问帐户时,如何在中间ProfileAccounts模型中按"数字"排序,而不是在帐户模型中使用默认的"名称"?

for acct_number in self.profile.accounts.all():
    pass
Run Code Online (Sandbox Code Playgroud)

这不起作用,但是我希望它如何访问这些数据的要点:

for scanline_field in self.scanline_profile.fields.all().order_by('number'):
    pass
Run Code Online (Sandbox Code Playgroud)

zal*_*lun 21

我刚刚经历过这个.

class Profile(models.Model):     
    accounts = models.ManyToManyField('project.Account',
                                      through='project.ProfileAccount')

    def get_accounts(self):
        return self.accounts.order_by('link_to_profile')


class Account(models.Model):
    name = models.CharField(max_length=32)


class ProfileAccount(models.Model):
    profile = models.ForeignKey('project.Profile')
    account = models.ForeignKey('project.Account', related_name='link_to_profile')
    number = models.PositiveIntegerField()

    class Meta:
        ordering = ('number',)
Run Code Online (Sandbox Code Playgroud)

我删除了除了主题以外的字段Article.name.这是我找到的最短的解决方案,不知道是否可以在2010年使用,但现在肯定是.

  • 在OP问题的情况下,他只需将self.profile.accounts.all()中的acct_number重写为`for self.profile.accounts.all()中的acct_number.order_by('link_to_profile')`.如果不清楚.您不必在`Profile`模型中添加`get_accounts`方法.Django总是在多对多表上创建一个外连接,因此根据该字段指定`order_by`就可以了. (2认同)

Mur*_*rlu 6

这对我有用:

Profile.objects.account.order_by('profileaccounts')
Run Code Online (Sandbox Code Playgroud)


Fal*_*gel 5

ManyToManyField管理器允许您直接从相关模型中选择/过滤数据,而无需在Django级别使用直通模型的任何模型连接...

同样

如果你试试:

pr = Profile.objects.get(pk=1)
pr.account.all()
Run Code Online (Sandbox Code Playgroud)

返回与该个人资料相关的所有帐户。如您所见,与直通模型ProfileAccount没有直接关系,因此此时您不能使用M2M关系...您必须对直通模型使用反向关系并过滤结果...

pr = Profile.objects.get(pk=1)
pr.profileaccount_set.order_by('number')
Run Code Online (Sandbox Code Playgroud)

将为您提供一个有序的查询集,但是在这种情况下,您在查询集中拥有的是profileaccount对象,而不是account对象...因此,您必须使用另一个django级别关系才能使用以下命令转到每个相关帐户:

pr = Profile.objects.get(pk=1)
for pacc in pr.profileaccount_set.order_by('number'):
    pacc.account
Run Code Online (Sandbox Code Playgroud)


小智 5

将相关名称添加到 ProfileAccounts,然后使用该“相关名称__编号”更改帐户中的顺序。请注意 related_name 和 number 之间的两个下划线。见下文:

class Accounts(models.Model):
    .
    .
    .
    class Meta:
        ordering = ('profile_accounts__number',)


class ProfileAccounts(models.Model):
    .
    .
    .
    account = models.ForeignKey('project.Accounts', related_name='profile_accounts')

    number = models.PositiveIntegerField()

    class Meta:
        ordering = ('number',)
Run Code Online (Sandbox Code Playgroud)

  • 在帐户中放置跨越订单子句的关系不会要求帐户上的每个查询也获取相关的个人资料帐户吗?这可能不是您想要做的。 (5认同)