Django查询一对多关系 [英] Django query in One to Many relationship

查看:143
本文介绍了Django查询一对多关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有2个表,Order和OrderDetails,在OrderDetails我有一个字段'product_type'。



从表中,我希望得到所有的product_type字段一个列表。



Order.objects.filter(pk = 1).annotate(type = F('product_type'))



我想要类型的值返回所有产品类型的列表,而不仅仅是第一个结果喜欢'椅子'。



Ex: type = ['chair','pencil']



型号:

  class Order(models.Model):
user = models.ForeignKey(User,related_name =orders)

class OrderDetails(models.Model):
order = models.ForeignKey(Order,related_name =details)
quantity = models.SmallIntegerField(null = False,blank = False)
product_type = models.CharField(null = False,blank = False)


解决方案

这不是你可以或应该尝试实现的东西e具有查询语句注释。这是因为注释只能用于聚合函数,如 Count Sum 等。



如果我正确理解您的问题,可以在遍历查询集时获取此信息:

  for订单在Order.objects.all():
types = order.details.values_list('product_type',flat = True)

您可以通过为每个订单预取相关的 OrderDetail 行来提高效率:



pre> 在Order.objects.prefetch_related('details')中的订单:
types = order.details.values_list('product_type',flat = True)
或者,您可以使用以下方法从每个订单中检索一些值:


$ b $ p $ b

  queryset = Order.objects.values('id','user_id','details__product_type')

它应该执行单个数据库查询。但是,请参阅这里有关如何运作的说明: https:// docs .djangoproject.com / en / 1.9 / ref / models / querysets /#values



您的查询器将输出dicts而不是模型实例。而您不会得到一个不错的 product_type s的列表,而您会收到如下重复的行:

  [
{'id':1,'user_id':1,'product_type':'chair'},
{'id':1,'user_id' :1,'product_type':'table'},
{'id':2,'user_id':3,'product_type':'chair'},
...
]

...所以你必须将这些行在python中分组到你想要的数据结构:

 用于集合导入OrdereredDict 

grouping = OrderedDict()
订单中的订单.objects.values('id','user_id','details__product_type'):
如果order ['id']未分组:
grouping [order ['id']] = {
'id':order ['id'],
'user_id':order ['user_id'],
'types':set(),
}
[顺序[ 'ID']] [ '类型']。添加(顺序['details__ product_type'])


I have 2 tables, Order and OrderDetails, on OrderDetails I have a field 'product_type'.

From the table Order I want to get all the product_type fields in a list.

Order.objects.filter(pk=1).annotate(type=F('product_type'))

I want the type value to return a list of all product types, not just the first result like 'chair'.

Ex: type = ['chair', 'pencil']

Models:

class Order(models.Model):
    user = models.ForeignKey(User, related_name="orders")

class OrderDetails(models.Model):
    order = models.ForeignKey(Order, related_name="details")
    quantity = models.SmallIntegerField(null=False, blank=False)
    product_type = models.CharField(null=False, blank=False)

解决方案

This is not something you can or should try to achieve with a queryset annotation. This is because annotations are only usable for aggregation functions like Count, Sum etc.

If I understood your question correctly, you can get this info when iterating over the queryset:

for order in Order.objects.all():
    types = order.details.values_list('product_type', flat=True)

You can make this more efficient by prefetching the related OrderDetail rows for each order:

for order in Order.objects.prefetch_related('details'):
    types = order.details.values_list('product_type', flat=True)

Alternatively, you can retrieve some values from each order using this method:

queryset = Order.objects.values('id', 'user_id', 'details__product_type')

It should do a single db query. However, see the notes here about how this works: https://docs.djangoproject.com/en/1.9/ref/models/querysets/#values

Your queryset will output dicts instead of model instances. And you will not get a nice list of product_types... instead you will get repeated rows like:

[
    {'id': 1, 'user_id': 1, 'product_type': 'chair'},
    {'id': 1, 'user_id': 1, 'product_type': 'table'},
    {'id': 2, 'user_id': 3, 'product_type': 'chair'},
    ...
]

...so you'll then have to group these rows in python into the data structure you want:

for collections import OrderedDict

grouped = OrderedDict()
for order in Order.objects.values('id', 'user_id', 'details__product_type'):
    if order['id'] not in grouped:
        grouped[order['id']] = {
            'id': order['id'],
            'user_id': order['user_id'],
            'types': set(),
        }
    grouped[order['id']]['types'].add(order['details__product_type'])

这篇关于Django查询一对多关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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