【问题标题】:Django Queryset - get last related object and filter by it's dataDjango Queryset - 获取最后一个相关对象并按其数据过滤
【发布时间】:2015-12-08 07:31:46
【问题描述】:

我有两个 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()

新的PersonData 对象会在其信息更改时添加,但旧的会保留。然后我想要一个过滤器,它会根据他们相关的最新PersonData 对象中的数据过滤人员。

我有以下查询集:

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)

但该过滤器会搜索与Person 关联的每个PersonData 对象。是否可以将此过滤器限制为仅最新的PersonData 对象?

【问题讨论】:

    标签: python django django-orm


    【解决方案1】:

    这是一种流行的查询类型,需要针对一个字段的唯一值的最新/最旧条目。

    我想说的是,如果您深入思考其他答案所暗示的内容,您就会明白它们没有达到目的。

    无法在单个 django 查询 (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) 中使用所需的过滤器获取 whole object

    我知道解决这个问题的方法之一是在Person 中为最新的PersonData 对象添加一个外键,并在每次创建PersonData 的新对象时更新它。

    【讨论】:

    • 你是对的。拥有最新的 PersonData 对象的外键将使事情变得容易得多。
    • 是的,它会的,并且假设您将外键字段命名为 persondata,您的查询将与现在完全相同,尽管我建议将其命名为 latest_data :)。
    【解决方案2】:

    所以你可以尝试查询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()
    

    【讨论】:

    • 这不会产生每个Person 的最新PersonData 对象,而是所有通过过滤器的最后一个PersonData 对象。
    猜你喜欢
    • 2015-10-15
    • 2021-11-24
    • 1970-01-01
    • 1970-01-01
    • 2013-05-06
    • 1970-01-01
    • 2017-01-21
    • 2013-05-08
    • 2016-01-15
    相关资源
    最近更新 更多