[英]Django Queryset order by a not directly related model's field
I have the following model design:我有以下 model 设计:
class Boat(models.Model):
name = models.CharField(max_length=30, null=False)
harbour = models.ForeignKey(Harbour, null=True, on_delete=models.SET_NULL)
class Harbour(models.Model):
name = models.CharField(max_length=60)
city = models.ForeignKey(City, null=True, related_name='city_harbours', on_delete=models.SET_NULL)
class City(models.Model):
name = models.CharField(max_length=80)
county = models.CharField(max_length=30, null=True)
class NearestCity(models.Model):
city = models.ForeignKey(City, related_name='city', null=False, on_delete=models.CASCADE)
near_city = models.ForeignKey(City, related_name='near_city', null=False, on_delete=models.CASCADE)
weight = models.DecimalField(null=False, max_digits=25, decimal_places=20)
A Boat
belongs to a Harbour
and a Harbour
belongs to a City
. Boat
属于Harbour
, Harbour
属于City
。
Not all Cities have a harbour related.并非所有城市都与港口有关。
NearestCity
is a table where is stored how close is a city the rest of the cities: The weight
is a decimal value that indicates how far is city from _near_city_. NearestCity
是一个表格,其中存储了城市的距离 rest: weight
是十进制值,表示城市距离_near_city_ 的距离。 The more smaller is the 'weight' value, the more close is city to near_city. “权重”值越小,城市与 near_city 越接近。 For example:
例如:
city near_city weight
---- --------- ------
London Rome 2.210103
London Manchester 0.113134
It means that Manchester is closer to London than Rome.这意味着曼彻斯特比罗马离伦敦更近。
Given a name of a city without any harbour related, for instance Berlin, a want to return all the boats of those closest cities that do have at least one harbour related.给定一个没有任何港口相关的城市的名称,例如柏林,想要归还那些最近的城市的所有船只,这些城市至少有一个港口相关。 This Boat's queryset must be ordered by
weight
DESC.这艘船的查询集必须按
weight
DESC 排序。
I am really newbie with django queryset and I tried to solved using annotate
with subqueries
, aggregations
, etc.. but I could not achieve it.我真的是 django 查询集的新手,我尝试使用带有
subqueries
、 aggregations
等的annotate
来解决。但我无法实现。
I would try raw sql .我会尝试原始 sql 。 Something like this should work:
像这样的东西应该工作:
city = selected_city_pk
sql = """
SELECT b.name, nc.weight, nc.near_city_id
FROM appname_nearestcity nc
JOIN appname_city c ON near_city_id = c.id
JOIN appname_harbour h ON near_city_id = h.city_id
JOIN appname_boat b ON h.id = b.harbour_id
WHERE nc.city_id = %s
ORDER BY nc.weight, b.name
"""
results = Boat.objects.raw(sql, [city,])
for r in results: print(r.id, r.name, r.weight, r.near_city_id)
# boat_id, boat_name, weight, near_city_id
>> 14 b-0-h-sochi-0 10 6
>> 15 b-0-h-sochi-1 10 6
>> 16 b-0-h-sochi-2 10 6
>> 17 b-1-h-sochi-2 10 6
>> 18 b-2-h-sochi-2 10 6
>> 11 b-0-h-rome-0 55 5
>> 12 b-1-h-rome-0 55 5
>> 13 b-2-h-rome-0 55 5
>> 4 b-0-h-brasilia-0 56 4
>> 7 b-0-h-brasilia-1 56 4
>> 10 b-0-h-brasilia-2 56 4
>> 5 b-1-h-brasilia-0 56 4
>> 8 b-1-h-brasilia-1 56 4
>> 6 b-2-h-brasilia-0 56 4
>> 9 b-2-h-brasilia-1 56 4
>> 1 b-0-h-beijin-0 93 2
>> 3 b-0-h-beijin-1 93 2
>> 2 b-1-h-beijin-0 93 2
Remember to replace table names with actual table names from your DB because Django adds app name prefixes to them.请记住用数据库中的实际表名替换表名,因为 Django 会向它们添加应用程序名称前缀。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.