简体   繁体   English

Django Queryset - 获取最后一个相关对象并按其数据过滤

[英]Django Queryset - get last related object and filter by it's data

I have two Django Models:我有两个 Django 模型:

class Person(models.Model):
    unique_id = models.CharField()

class PersonData(models.Model):
    person = models.ForeignKey('Person')
    phone = models.CharField()
    email = models.CharField()
    date = models.DateTimeField()

New PersonData objects are added when their information changes, but old ones are kept.当信息发生变化时,会添加新的PersonData对象,但保留旧的对象。 And then I want to have a filter, which will filter persons by their data from the latest PersonData object they are related to.然后我想要一个过滤器,它将根据他们相关的最新PersonData对象中的数据过滤人员。

I have the following queryset:我有以下查询集:

filter_email = "email@example.com"
filter_phone = "964477425"

qs = Person.objects.all()

if filter_email:
    qs = qs.filter(persondata__email__icontains=filter_email)
if filter_phone:
    qs = qs.filter(persondata__phone__icontains=filter_phone)

But that filter searches through every PersonData object associated with Person .但该过滤器会搜索与Person关联的每个PersonData对象。 Is it possible to restrict this filter to only the latest PersonData object?是否可以将此过滤器限制为仅最新的PersonData对象?

It is a popular type of query where latest/oldest entry against unique values of one field are desired.这是一种流行的查询类型,其中需要针对一个字段的唯一值的最新/最旧条目。

I would like to say that if you think over what other answers suggest deeply, you'll understand they do not serve the purpose.我想说的是,如果您深入思考其他答案的建议,您就会明白它们并没有达到目的。

There is no way to fetch the whole object with desired filter in single django query ( Note that it is possible to get one field but not all fields, also it is possible to fetch all fields in raw **sql** queries ).无法在单个Django查询中使用所需的过滤器获取whole objectNote that it is possible to get one field but not all fields, also it is possible to fetch all fields in raw **sql** queries )。

One of the ways I know to tackle this problem is to have a foreign-key in Person to the latest PersonData object, and update it each time new object of PersonData is created.我知道解决这个问题的方法之一是在Person拥有一个指向最新PersonData对象的外键,并在每次创建PersonData新对象时更新它。

So you could try query to PersonData model:所以你可以尝试查询PersonData模型:

qs = PersonData.objects.filter()

if filter_email:
    qs = PersonData.objects.filter(email__icontains=filter_email)
if filter_phone:
    qs = PersonData.objects.filter(phone__icontains=filter_phone)

# Cache Person object and pick the last
qs = qs.select_related('person').last()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM