仅当外键未保存为属性时,Django 才过滤相关模型
Django filter a related model only if a foreign key is not saved as an attribute
我有以下型号:
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] 使用:
从django.db.models导入Q
q1 = Q(count__gt=2) # 不止两次,所以也是一个中间值
q2 = Q(count__gt=1) & ( # 不止一个,所以至少有一个 start/stop 不匹配
~Q(first_stop=<i>specific_location</i>) |
~Q(last_stop=<i>specific_location</i>)
)
q3 = ( # 两个位置不匹配
~Q(first_stop=<i>specific_location</i>) &
~Q(last_stop=<i>specific_location</i>)
)
Route.objects.filter(
停止=<i>specific_location</i>
)。注释(
cnt=计数('stop')
)。筛选(
q1 |问题2 |问题3
)
可以使用双下划线 (__
) 来查看“through”关系。因此,我们检索 Route
s,其中有一个相关的 stop
即 specific_location
,但它不是 first_stop
或 last_stop
.
我有以下型号:
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] 使用:
从django.db.models导入Q
q1 = Q(count__gt=2) # 不止两次,所以也是一个中间值
q2 = Q(count__gt=1) & ( # 不止一个,所以至少有一个 start/stop 不匹配
~Q(first_stop=<i>specific_location</i>) |
~Q(last_stop=<i>specific_location</i>)
)
q3 = ( # 两个位置不匹配
~Q(first_stop=<i>specific_location</i>) &
~Q(last_stop=<i>specific_location</i>)
)
Route.objects.filter(
停止=<i>specific_location</i>
)。注释(
cnt=计数('stop')
)。筛选(
q1 |问题2 |问题3
)
可以使用双下划线 (__
) 来查看“through”关系。因此,我们检索 Route
s,其中有一个相关的 stop
即 specific_location
,但它不是 first_stop
或 last_stop
.