Django 仅在外键未保存为属性时才过滤相关模型



我有以下型号:

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,其中有一个相关的stopspecific_location,但它不是first_stoplast_stop

相关内容

  • 没有找到相关文章

最新更新