如何在Django中执行嵌套的反向查询集

时间:2019-06-12 21:47:09

标签: python django

我需要在Django中创建双反向queryset,在代码中有更多解释:

模型

class Book(models.Model):
    date = models.DateTimeField(auto_now=True)
    book_name = models.CharField(max_length=150)
    book_level = models.ForeignKey(Level, on_delete=CASCADE)
    book_subject = models.ForeignKey(Subject, on_delete=CASCADE)
    book_teacher = models.ForeignKey(Teacher, on_delete=CASCADE, null=True, blank=True)
    book_comission = models.DecimalField(max_digits=19, decimal_places=5, null=True, blank=True)
    book_black_papers = models.IntegerField()
    book_color_papers = models.IntegerField()
    book_paper_cost = models.DecimalField(max_digits=19, decimal_places=5)
    book_ink_cost = models.DecimalField(max_digits=19, decimal_places=5)
    book_color_ink_cost = models.DecimalField(max_digits=19, decimal_places=5)
    book_cover_cost = models.DecimalField(max_digits=19, decimal_places=5)
    supplier = models.ForeignKey(Supplier, on_delete=CASCADE, null=True, blank=True)
    book_total_cost = models.DecimalField(max_digits=19, decimal_places=5)
    book_sell_price = models.DecimalField(max_digits=19, decimal_places=5)
    viewed_by = models.ManyToManyField(User)
    is_double_pages = models.BooleanField(default=False)
    is_hidden = models.BooleanField(default=False)
    image1 = ProcessedImageField(upload_to='book_image',
                                 processors=[ResizeToFill(440, 262)],
                                 format='JPEG',
                                 options={'quality': 60}, blank=True, null=True)
    image2 = ProcessedImageField(upload_to='book_image',
                                 processors=[ResizeToFill(440, 262)],
                                 format='JPEG',
                                 options={'quality': 60}, blank=True, null=True)
    image3 = ProcessedImageField(upload_to='book_image',
                                 processors=[ResizeToFill(440, 262)],
                                 format='JPEG',
                                 options={'quality': 60}, blank=True, null=True)
    image4 = ProcessedImageField(upload_to='book_image',
                                 processors=[ResizeToFill(440, 262)],
                                 format='JPEG',
                                 options={'quality': 60}, blank=True, null=True)
    published_online = models.BooleanField(default=False)


class VIPSellInvoice(models.Model):
    ordered = 'تحت التنفيذ'
    delivered = 'منتهية'
    canceled = 'ملغاة'
    invoice_choices = (
        (ordered, 'تحت التنفيذ'),
        (delivered, 'منتهية'),
        (canceled, 'ملغاة'),
    )

    date = models.DateTimeField(auto_now=True)
    user = models.ForeignKey(User, on_delete=PROTECT)
    client = models.ForeignKey(VipClient, on_delete=PROTECT)
    total = models.DecimalField(max_digits=19, decimal_places=5, default=0)
    status = models.CharField(max_length=160, choices=invoice_choices)
    delivery = models.ForeignKey(Delivery, on_delete=PROTECT, null=True, blank=True)
    delivery_price = models.DecimalField(max_digits=19, decimal_places=5, default=0, null=True, blank=True)
    delivery_notes = models.CharField(max_length=500, null=True, blank=True)
    is_done = models.BooleanField(default=False)

class VipPriceList(models.Model):
    book_name = models.ForeignKey(Book, on_delete=CASCADE)
    book_price = models.DecimalField(max_digits=19, decimal_places=5)
    book_client = models.ForeignKey(VipClient, on_delete=CASCADE)
    book_client_comission = models.DecimalField(max_digits=19, decimal_places=5)


class VipClient(models.Model):
    client_name = models.CharField(max_length=150)
    client_address = models.CharField(max_length=150)
    client_phone1 = models.CharField(max_length=20)
    client_phone2 = models.CharField(max_length=20)
    client_note = models.CharField(max_length=500, null=True, blank=True)
    client_balance = models.DecimalField(max_digits=19, decimal_places=5, default=0)
    client_commission = models.DecimalField(max_digits=19, decimal_places=5, default=0)

正在尝试在最终查询集中获取VIPpricelists`` that belong to the客户that belongs to the current贵宾发票then get the Book_set`,以便我处理。

这是我在视图中尝试如何调用的方式:

def vip_sellinvoice_add_books(request, pk):
    current_vip_invoice = get_object_or_404(models.VIPSellInvoice, pk=pk)
    test = current_vip_invoice.client.vippricelist_set.all().book_set.all()
    context = {
        'test': test,
    }
    return render(request, 'vip/vip_sell_invoice_add_books.html', context)

我得到了错误:

“ QuerySet”对象没有属性“ book_set”

那么,是否有可能在Django中创建这样的嵌套反向查询集,或者有更简单的方法呢?

1 个答案:

答案 0 :(得分:1)

在这种情况下,通常需要从Book对象本身进行查询,例如:

Book.objects.filter(vippricelist__book_client__vIPsellinvoice=current_vip_invoice)

因此,我们在这里查询存在一个Book对象的VipPriceList对象,该对象具有一个book_client字段,该字段引用与{{ 1}})。