以下是我的模型设置的摘要:
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',)
然后,当我访问帐户时,如何在中间ProfileAccounts模型中按“数字”排序,而不是在帐户模型中使用默认的“名称”?:
for acct_number in self.profile.accounts.all():
pass
这不起作用,但是我希望它如何访问这些数据的要点是:
for scanline_field in self.scanline_profile.fields.all().order_by('number'):
pass
答案 0 :(得分: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',)
除了Article.name
之外,我删除了偏离主题的字段。
这是我发现的最短的解决方案,不知道是否可以在2010年使用,但现在肯定是。
答案 1 :(得分:5)
ManyToManyField管理器允许您直接从相关模型中选择/过滤数据,而无需在django级别上使用直通模型的任何模型连接...
同样地,
如果您尝试:
pr = Profile.objects.get(pk=1)
pr.account.all()
返回与该个人资料相关的所有帐户。如您所见,与直通模型ProfileAccount没有直接关系,因此此时您无法使用M2M关系...您必须使用与贯穿模型的反向关系并过滤结果...
pr = Profile.objects.get(pk=1)
pr.profileaccount_set.order_by('number')
会给你一个有序的查询集,但是,在这种情况下,你在queryset中拥有的是profileaccount对象,而不是帐户对象......所以你必须使用另一个django级别关系来转到每个相关的帐户:
pr = Profile.objects.get(pk=1)
for pacc in pr.profileaccount_set.order_by('number'):
pacc.account
答案 2 :(得分:2)
这对我有用:
Profile.objects.account.order_by('profileaccounts')
答案 3 :(得分:1)
配置文件中有一个拼写错误(当我认为你的意思是“帐户”时,它是“accout”),但更重要的是你在模型中混合了你的单数/复数形式。
在Django中,练习通常是将您的类命名为单数,而您的ManyToManyField名称为复数。所以:
class Profile(models.Model):
name = models.CharField(max_length=32)
accounts = models.ManyToManyField(
'Account',
through='ProfileAccount'
)
def __unicode__(self)
return self.name
class Account(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 ProfileAccount(models.Model):
profile = models.ForeignKey(Profile)
account = models.ForeignKey(Account)
number = models.PositiveIntegerField()
class Meta:
ordering = ('number',)
我对您尝试使用此模型所做的事情感到有些困惑,但如果您进行了这些更改,则for acct_number in self.profile.accounts.all().order_by('number'):
应该可以正常工作。假设没有其他问题。
答案 4 :(得分:1)
将相关名称添加到ProfileAccounts,然后使用“related_name__number”更改Accounts中的顺序。请注意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',)
答案 5 :(得分:0)
这个特定问题的最简单解决方案似乎是
for acct in self.profile.accounts.order_by('profileaccounts'):
pass
答案 6 :(得分:0)
我在很多模型上都有这个,但在我看来(并且与其他所有答案不同)你不应该再次指定order_by
,因为,它是it,已在through
模型中指定。再次指定它会打破DRY(不要重复自己)原则。
我会用:
qs = profile.profileaccounts_set.all()
这将使用您配置的排序提供与配置文件关联的ProfileAccounts集。然后:
for pa in qs:
print(pa.account.name)
对于奖励积分,您还可以在查询中使用select_related
来加快整个过程。