Django-过滤相关对象

时间:2019-10-02 17:13:07

标签: python django django-filter

比方说,我有一个位置列表,其中每个位置都有一些对象的列表。我想确保获得这些位置,但具有过滤的对象列表。

这是models.py的结构:

class Location(models.Models):
    # fields


class LocationObject(models.Models):
    location = models.ForeignKey(Location, related_name="objects_list")
    # other fields that are used in filtering

这是我进行过滤的方法:

locations = Location.objects.all()

if request_square_from:
    locations = locations.filter(objects_list__size__gte=request_square_from)

if request_square_to:
    locations = locations.filter(objects_list__size__lte=request_square_to)

# Other filters ...

问题在于,通过使用这种过滤方法,我在每个位置获得了一个对象列表,其中至少有一个 个满足locations.filter()条件的对象。这不是我真正需要的。我需要排除不满足LocationObject方法中条件的每个对象(我的意思是filter())。

有什么想法吗?

更新。一点澄清

此列表的外观如下:

Location #1
   - Object 1 (size=40)
   - Object 2 (size=45)
   - Object 3 (size=30)

Location #2
   - Object 4 (size=20)
   - Object 5 (size=25)

我想通过size属性来过滤位置的每个对象。假定这种情况:Location.objects.filter(objects_list__size__gte=40)。这将匹配甚至仅包含一个具有此属性的列表条目的位置。这不是我需要的不是。预期结果应为:

Location #1:
   - Object 1 (size=40)
   - Object 2 (size=45)

3 个答案:

答案 0 :(得分:0)

假设您确实希望那些位置至少具有一个满足两个条件的对象,则可以执行以下操作:

locations = locations.filter(objects_list__size__gte=request_square_from, 
                             objects_list__size__lte=request_square_to)

但是由于不确定两个参数,因此不能这样做。但是,您可以使用Q个对象来实现它:

from django.db.models import Q

# ...    
locations = Location.objects.all()
q = Q()    
if request_square_from:
    q &= Q(objects_list__size__gte=request_square_from)    
if request_square_to:
    q &= Q(objects_list__size__lte=request_square_to)    
if q:
    locations = locations.filter(q)

答案 1 :(得分:0)

如果我没记错,您想要的是exclude()

filter()用于过滤出所有必需的对象。因此,您将使用:

locations = locations.filter(objects_list__size__gte=request_square_from)

这将为您提供满足此条件的所有对象。

但是如果要排除匹配的查询。您需要使用exclude()

locations = locations.exclude(objects_list__size__gte=request_square_from)

这将为您提供不满足条件的对象,并返回其余对象。

答案 2 :(得分:0)

根据您的更新,您需要一个位置对象列表,而不是位置列表,因此,不要过滤位置,而是过滤位置对象!

objects = LocationObject.objects.all()
if request_square_from:
    objects = objects.filter(size__gte=request_square_from)

if request_square_to:
    objects = objects.filter(size__lte=request_square_to)

不受限制,只能过滤外键,您可以过滤任何Model实例。

如果在此之后,您想要任何对象的位置,只需...

objects[0].location