比方说,我有一个位置列表,其中每个位置都有一些对象的列表。我想确保获得这些位置,但具有过滤的对象列表。
这是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)
答案 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