python 是否可以将不同模型的查询集合并为一个查询集或列表并按日期排序

osh3o9ms  于 2023-05-05  发布在  Python
关注(0)|答案(1)|浏览(95)

models.py

# Customer Model

class Customer(models.Model):
    name =models.CharField(max_length=100)
    primary_contact = models.CharField(max_length=10)
    secondary_contact = models.CharField(max_length=10, blank=True)
    address = models.TextField(blank=True)
    

    def __str__(self):
        return self.name
    
    def get_absolute_url(self):
        return reverse('customers')
    

# Issue Model

class Issue(models.Model):
    date_time = models.DateTimeField(default=datetime.now)
    date = models.DateField(auto_now_add = True)
    tt = models.CharField(default='SB', max_length=3)
    voucher = models.CharField(blank = True, default='', max_length=6)
    customer = models.ForeignKey(Customer, on_delete = models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE, )
    quantity = models.PositiveIntegerField()
    kt = models.IntegerField()
    rate = models.FloatField()
    vat = models.IntegerField(default=15)
    discount = models.IntegerField(blank = True, default = 0)
    note = models.CharField(blank = True, default='', max_length=100)
    amount = models.IntegerField(blank = True, default = 0)


    @property
    def kt_21(self):
        return round(self.kt / 21 * self.quantity , 2)
    
    @property
    def vat_amt(self):
        return (self.quantity * self.rate - self.discount) * self.vat/100
    

    # Total amount exclusive of VAT
    @property
    def tot_amount(self):
        return self.quantity * self.rate
    
    
    # Total amount inclusive of VAT
    @property
    def total_amt(self):
        return self.quantity * self.rate + self.vat_amt
    
    def get_absolute_url(self):
        return reverse('issue-hist')

    def __str__(self):
        return  str(self.customer) + " - "+ str(self.tot_amount)+' SAR'
    

# Receive Model

class Receive(models.Model):
    date_time = models.DateTimeField(default=datetime.now)
    date = models.DateField(auto_now_add = True)
    tt = models.CharField(default='RB', max_length=3)
    voucher = models.CharField(blank = True, default='', max_length=6)
    customer = models.ForeignKey(Customer, on_delete = models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE, )
    quantity = models.PositiveIntegerField()
    kt = models.IntegerField()
    rate = models.FloatField()
    vat = models.IntegerField(default=0)
    discount = models.IntegerField(blank = True, default = 0)
    note = models.CharField(blank = True, default='', max_length=100)
    amount = models.IntegerField(blank = True, default = 0)

    @property
    def kt_21(self):
        return round(self.kt / 21 * self.quantity , 2)
    
    @property
    def vat_amt(self):
        return self.quantity * self.rate * self.vat/100
    
    @property
    def tot_amount(self):
        return self.quantity * self.rate

    @property
    def total_amt(self):
        return self.quantity * self.rate + self.vat_amt
    
    def get_absolute_url(self):
        return reverse('rec-hist')

    def __str__(self):
        return  str(self.customer) + " - "+ str(self.tot_amount)+' SAR'

# Sales-Retrun Model

class SalesReturn(models.Model):

    date_time = models.DateTimeField(default=datetime.now)
    date = models.DateField(auto_now_add = True)
    tt = models.CharField(default='SRB', max_length=3)

    voucher = models.CharField(blank = True, default='', max_length=6)
    customer = models.ForeignKey(Customer, on_delete = models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE, )
    quantity = models.PositiveIntegerField()
    kt = models.IntegerField()
    rate = models.FloatField()
    vat = models.IntegerField(default=15)
    discount = models.IntegerField(blank = True, default = 0)
    note = models.CharField(blank = True, default='', max_length=100)
    amount = models.IntegerField(blank = True, default = 0)

    @property
    def kt_21(self):
        return round(self.kt / 21 * self.quantity , 2)
    
    @property
    def vat_amt(self):
        return self.quantity * self.rate * self.vat/100
    
    @property
    def tot_amount(self):
        return self.quantity * self.rate

    @property
    def total_amt(self):
        return self.quantity * self.rate + self.vat_amt
    
    def get_absolute_url(self):
        return reverse('sr-hist')

    def __str__(self):
        return  str(self.customer) + " - "+ str(self.tot_amount)+' SAR'

我想查询一个特定客户的所有收货、发货和退货情况,我已经实现了。但是现在我想把这3个查询集合并成一个查询集,并按“date_time”排序。我试着把它们都附加到一个列表中并对它们进行排序,但这不起作用,它确实给出了一个排序列表,但它没有按日期顺序对它们进行排序,它以一种方式对它们进行排序,其中所有的问题,接收和返回都被分组在一起并按日期排序。
这就是我所尝试的:

issues = list((Issue.objects.filter(customer = cust).order_by('-date_time'))
receives = list(Receive.objects.filter(customer = cust).order_by('-datetime')
   for issue in issues:
        x.append(issue)

    for rec in receives:
        x.append(rec)

我也尝试使用sort(),但它总是返回None

x.sort(key = lambda r: r.date_time)
mdfafbf1

mdfafbf11#

您可以处理四个查询,然后将它们合并到同一列表中:

from operator import attrgetter

klasses = [Issue, Receive, SalesReturn]
customer = None  # some customer
result = sorted(
    [
        m
        for klass in klasses
        for m in klass.objects.filter(customer=customer).order_by('date_time')
    ],
    key=attrgetter('date_time'),
)

.order_by('date_time')子句不是必需的,但是如果数据已经是部分排序的,Timsort 通常会执行得更好,所以我们可以(稍微)提高这个过程。
我也尝试使用sort(),但它总是返回None
Sort always 返回None:它不返回一个排序的列表,它修改了列表的顺序,所以在.sort()调用之后,x被排序。

相关问题