我有以下型号:
class Route(Model):
first_stop = models.ForeignKey(
Stop,
help_text="The departure point",
)
last_stop = models.ForeignKey(
Stop,
help_text="The destination point",
)
class Stop(Model):
location = models.CharField(max_length=100)
route = models.ForeignKey(
Route,
related_name="stops",
related_query_name="stop",
help_text="the route that this stop belongs to",
)
路径至少有两个停靠点,并且对第一个和最后一个停靠点的引用将保留为属性。
我正在尝试过滤经过特定位置的路线,而不仅仅是在第一站或最后一站。
如果该位置仅出现在其第一个或最后一个停靠点,则应排除该路径。
如果该位置存在于中间停靠点(不是first_stop或last_stop),则无论该位置是否也存在于其第一个或最后一个停靠点上,都应包括该路径。
如果一条路线只有两个停靠点,则应将其排除在外。
我提出了一个解决方案,但它非常冗长和丑陋,可能效率低下:
routes_to_exclude = []
for route in result: # result is a queryset
matched_stops = False
for stop in route.stops.exclude(
pk__in=(route.first_stop_id, route.last_stop_id)
): # to make sure the desired location isn't only on the first or last stop
if str(stop.location) == desired_location:
matched_stops = True
break
if matched_stops:
routes_to_exclude.append(route.pk)
result = result.exclude(pk__in=routes_to_exclude)
有没有更好的方法来实现此过滤器?
你可以用以下命令.filter(…)
[Django-doc]:
from django.db.models import Q
q1 = Q(count__gt=2) # more than twice, so also an intermediate
q2 = Q(count__gt=1) & ( # more than one, so at least one start/stop should not match
~Q(first_stop=specific_location) |
~Q(last_stop=specific_location)
)
q3 = ( # both locations do not match
~Q(first_stop=specific_location) &
~Q(last_stop=specific_location)
)
Route.objects.filter(
stop=specific_location
).annotate(
cnt=Count('stop')
).filter(
q1 | q2 | q3
)
可以使用双下划线(__
)来查看">透视"关系。因此,我们检索Route
,其中有一个相关的stop
是specific_location
,但它不是first_stop
或last_stop
。