Ahmed Wagdi
Ahmed Wagdi

Reputation: 4401

how to perform a nested reverse query set in django

I need to create double reverse queryset in Django, explained more in the code:

The models

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)

Am trying to get the VIPpricelists`` that belong to theclientthat belongs to the currentVip Invoicethen get theBook_set` in the final queryset so that I can deal with it.

here is howw i tried to call it in my views:

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)

I get the error:

'QuerySet' object has no attribute 'book_set'

so, is it possible to create such a nested reverse querysets in Django or there is a simpler way to do it?

Upvotes: 1

Views: 260

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477160

In that case, you usually query from the Book object itself, like:

Book.objects.filter(vippricelist__book_client__vIPsellinvoice=current_vip_invoice)

So here we query for Books for which there exists a VipPriceList object which has a book_client field that refers to a VipClient that is related to the current_vip_invoice).

Upvotes: 1

Related Questions