简体   繁体   English

Django 按不直接相关模型字段的查询集顺序

[英]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)

Brief explanation:简要说明:

  • A Boat belongs to a Harbour and a Harbour belongs to a City . Boat属于HarbourHarbour属于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.这意味着曼彻斯特比罗马离伦敦更近。

Problem to solve:要解决的问题:

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 查询集的新手,我尝试使用带有subqueriesaggregations等的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.

相关问题 Django-通过向后相关模型的字段对QuerySet进行排序 - Django - sort QuerySet by backwards related model's field Django queryset按相关模型的顺序不同 - Django queryset order by related model with distinct Django查询集按相关字段中的最新值排序 - Django queryset order by latest value in related field Django:如何通过相关的 object(如果存在)和字段(如果不存在)来订购查询集? - Django: how to order a queryset by a related object if it exists and by a field if it doesn't? django:如何在ManyToManyField(通过)相关模型中的字段上对查询集排序 - django: How to order the queryset on a field in ManyToManyField (through) related models Django:按相关模型字段从查询集中删除重复项(分组依据) - Django: remove duplicates (group by) from queryset by related model field 如何在相关模型中按查询集排序查询集 - How to order queryset by queryset in related model 使用 values() 时过滤 Django 查询集的相关 ManyToMany 字段 - Filtering a Django queryset's related ManyToMany field when using values() Django 模型字段实际上是对相关模型中字段的引用 - Django model field that's actually a reference to a field in a related model django queryset能用现有值+ 1更新自己模型的字段吗? - django queryset able update own model's field with existing value + 1?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM