Python Django:如何编写查询以使用多列进行排序,通过模板显示

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20256909/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 20:02:04  来源:igfitidea点击:

Django: How to write query to sort using multiple columns, display via template

pythondjangopostgresqlsortingdjango-queryset

提问by pete

I'm quite new to Django, and not too experienced with MVC, DB queries.

我对 Django 很陌生,对 MVC、DB 查询也不太熟悉。

I have a Customer table which includes customer_name, city_name, as well as a state_name (pulled from a foreign key table). In the HTML, I'm trying to display the results in a list first sorted alphabetically by state_name, then by city_name, then by customer_name name. Like so..

我有一个 Customer 表,其中包括 customer_name、city_name 和 state_name(从外键表中提取)。在 HTML 中,我尝试将结果显示在列表中,首先按 state_name 的字母顺序排序,然后按 city_name,然后按 customer_name 名称。像这样..

ARIZONA
   PHOENIX
     AAA, Inc.
     BBB, LLC.

   SCOTTSDALE
     AAA, LLC.
     DDD, Corp.

CALIFORNIA
   ANAHEIM
     ...

My model.py is as follows:

我的model.py如下:

from django.db import models

class Customer(models.Model):
    def __unicode__(self):
        return self.customer_name

    customer_name = models.CharField(max_length=60)
    city_name = models.CharField(max_length=30)
    state = models.ForeignKey('State')

class State(models.Model):
    def __unicode__(self):
         return self.state_name

    state_name = models.CharField(max_length=20)
    state_code = models.CharField(max_length=2)

In my urls.py, I have:

在我的 urls.py 中,我有:

url("^customers/$",
    direct_to_template,
    {'template': 'pages_fixed/customers.html',
    'extra_context': {'customers': Customer.objects.all().order_by('state')}},
    name='customers'),

And in my HTML, I have a working template as:

在我的 HTML 中,我有一个工作模板:

    <div class='customers'>
        {% for customer in customers %}
            <div class='block_customer'>
                <p>{{ customer.state.state_name }}</p>
                <p>{{ customer.city_name }}</p>
                <p>{{ customer.customer_name }}</p>
            </div>
        {% endfor %}
    </div>

It's all sort of working but obviously not sorting correctly and I'm not sure what's the best way to design it. I tried some inner loops with the templates, was hoping the templates would let me define some sorting rules but this doesn't seem to be supported/correct. I suspect that I need to query the data differently or pre-sort them in code ahead of time? I'm not sure if this would be done in the View (what is Django's form of Controller?).. If anyone could point me in the right direction, that would be MUCH appreciated!

这一切都在工作,但显然排序不正确,我不确定设计它的最佳方式是什么。我用模板尝试了一些内部循环,希望模板能让我定义一些排序规则,但这似乎不受支持/正确。我怀疑我需要以不同的方式查询数据或提前在代码中对它们进行预排序?我不确定这是否会在视图中完成(Django 的控制器形式是什么?).. 如果有人能指出我正确的方向,那将不胜感激!

采纳答案by juliocesar

There are several levels for display ordered models objects in template, each one overwrite the previous level:

模板中显示有序模型对象有几个级别,每个级别都会覆盖上一级:

  1. (MODEL LEVEL) Meta attribute orderingas shows @Bithin in his answer (more on django docs)
  2. (VIEW LEVEL) QuerySet order_bymethodas you have tried in your view example, which would works as you want if add other fields to sort:

    Customer.objects.order_by('state', 'city_name', 'customer_name')

    (more on django docs). Note that .all()is not needed here.

  3. (TEMPLATE LEVEL) regrouptemplate tagneed to use nested in your sample (more on django docs)
  1. (模型级别)元属性ordering如@Bithin 在他的回答中所示(更多关于django 文档
  2. (VIEW LEVEL) QuerySetorder_by方法,正如您在视图示例中尝试过的那样,如果添加其他字段进行排序,它将按您的需要工作:

    Customer.objects.order_by('state', 'city_name', 'customer_name')

    更多关于Django 文档)。注意.all()这里不需要。

  3. (模板级别)regroup模板标签需要嵌套在您的示例中使用(更多关于django 文档

回答by Bithin

You can specify the ordering inside the model,

您可以指定模型内的排序,

class Customer(models.Model):

    customer_name = models.CharField(max_length=60)
    city_name = models.CharField(max_length=30)
    state = models.ForeignKey('State')

    def __unicode__(self):
        return self.customer_name

    class Meta:
           ordering = ['customer_name', 'city_name', 'state']

Hope this helps.

希望这可以帮助。

回答by DanielB

If you want to order by some field of the "master" model, in this case state, you must write something like this:

如果要按“主”模型的某个字段(在本例中为 state)进行排序,则必须编写如下内容:

Customer.objects.order_by('state__state_name', 'city_name', 'customer_name')

Take a look of state__state_name, the double _ after the first state, make access to the field of that model.

看一下 state__state_name,第一个状态之后的双 _,访问该模型的字段。