使用来自django的“额外字段”与额外字段的多对多关系

时间:2022-10-04 16:30:25

Django documents give this example of associating extra data with a M2M relationship. Although that is straight forward, now that I am trying to make use of the extra data in my views it is feeling very clumsy (which typically means "I'm doing it wrong").

Django文档给出了将额外数据与M2M关系相关联的示例。虽然这是直截了当的,但现在我试图在我的视图中使用额外的数据,它感觉非常笨拙(这通常意味着“我做错了”)。

For example, using the models defined in the linked document above I can do the following:

例如,使用上面链接文档中定义的模型,我可以执行以下操作:

# Some people
ringo = Person.objects.create(name="Ringo Starr")
paul = Person.objects.create(name="Paul McCartney")
me = Person.objects.create(name="Me the rock Star")
# Some bands
beatles = Group.objects.create(name="The Beatles")
my_band = Group.objects.create(name="My Imaginary band")
# The Beatles form
m1 = Membership.objects.create(person=ringo, group=beatles,
    date_joined=date(1962, 8, 16),
    invite_reason= "Needed a new drummer.")
m2 = Membership.objects.create(person=paul, group=beatles,
    date_joined=date(1960, 8, 1),
    invite_reason= "Wanted to form a band.")
# My Imaginary band forms
m3 = Membership.objects.create(person=me, group=my_band,
    date_joined=date(1980, 10, 5),
    invite_reason= "Want to be a star.")
m4 = Membership.objects.create(person=paul, group=my_band,
    date_joined=date(1980, 10, 5),
    invite_reason= "Wanted to form a better band.")

Now if I want to print a simple table that for each person gives the date that they joined each band, at the moment I am doing this:

现在,如果我想要打印一个简单的表格,每个人都给出了他们加入每个乐队的日期,此刻我正在这样做:

bands =  Group.objects.all().order_by('name')

for person in Person.objects.all():
    print person.name, 
    for band in bands:
        print band.name,
        try:
            m = person.membership_set.get(group=band.pk)
            print m.date_joined,
        except:
            print 'NA',
    print ""

Which feels very ugly, especially the "m = person.membership_set.get(group=band.pk)" bit. Am I going about this whole thing wrong?

这感觉非常难看,尤其是“m = person.membership_set.get(group = band.pk)”位。我是不是错了?

Now say I wanted to order the people by the date that they joined a particular band (say the beatles) is there any order_by clause I can put on Person.objects.all() that would let me do that?

现在说我想在他们加入一个特定乐队的日期(比如披头士乐队)订购这些人是否有任何order_by子句我可以放在Person.objects.all()上让我这样做?

Any advice would be greatly appreciated.

任何建议将不胜感激。

1 个解决方案

#1


3  

You should query the Membership model instead:

您应该查询成员资格模型:

members = Membership.objects.select_related('person', 'group').all().order_by('date_joined')

for m in members:
    print m.band.name, m.person.name, m.date_joined

Using select_related here we avoid the 1 + n queries problem, as it tells the ORM to do the join and selects everything in one single query.

在这里使用select_related我们避免了1 + n查询问题,因为它告诉ORM进行连接并在一个查询中选择所有内容。

#1


3  

You should query the Membership model instead:

您应该查询成员资格模型:

members = Membership.objects.select_related('person', 'group').all().order_by('date_joined')

for m in members:
    print m.band.name, m.person.name, m.date_joined

Using select_related here we avoid the 1 + n queries problem, as it tells the ORM to do the join and selects everything in one single query.

在这里使用select_related我们避免了1 + n查询问题,因为它告诉ORM进行连接并在一个查询中选择所有内容。