使用“额外字段”从django与多个字段的多对多关系 [英] Using the "extra fields " from django many-to-many relationships with extra fields

查看:95
本文介绍了使用“额外字段”从django与多个字段的多对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Django文件给了这个例子是将额外的数据与M2M关系相关联。虽然这是直截了当的,现在我试图利用额外的数据在我的意见,它感觉很笨拙(这通常意味着我做错了)。



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

 #有些人
ringo = Person.objects.create(name =Ringo Starr)
paul = Person.objects.create(name =Paul McCartney)
me = Person.objects.create(name =我是摇滚之星)
#有些乐队
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 =需要一个新的鼓手)
m2 = Membership.objects.create(person = paul,group = beatles,
date_joined = date 1960,8,1),
invite_reason =想要组合一个乐队)
#我的虚拟乐队形式
m3 = Membership.objects.create(person = me,group = my_band ,
date_joined = date(1980,10,5),
invite_reason =想成为一个明星。
m4 = Membership.objects.creat e(person = paul,group = my_band,
date_joined = date(1980,10,5),
invite_reason =想要形成一个更好的乐队)

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

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

在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


现在说我想在他们加入某个乐队的日期(比如说,beatles)有秩序的人条款我可以放在Person.objects.all(),这将让我这样做?



任何建议将不胜感激。

解决方案

您应该查询会员模型:

  member(person,group)。all()。order_by('date_joined')

成员中的m:
print m.band.name,m .person.name,m.date_joined

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


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").

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?

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?

Any advice would be greatly appreciated.

解决方案

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.

这篇关于使用“额外字段”从django与多个字段的多对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆