代码之家  ›  专栏  ›  技术社区  ›  Davtho1983

按django 2.0中的字段值排序

  •  1
  • Davtho1983  · 技术社区  · 7 年前

    这个问题就像 django sorting 但我不能让任何解决方案发挥作用。

    我有以下型号:

    from django.db import models
    from django.contrib.auth.models import User
    
    class Product(models.Model):
    
        title = models.CharField(max_length=200)
        pub_date = models.DateTimeField()
        body = models.TextField()
        url = models.TextField()
        image = models.ImageField(upload_to='images/')
        icon = models.ImageField(upload_to='images/')
        votes_total = models.IntegerField(default=1)
        hunter = models.ForeignKey(User, on_delete=models.CASCADE)
    
        def summary(self):
            return self.body[:50]
    
        def pub_date_pretty(self):
            return self.pub_date.strftime('%b %e %Y')
    
        def __str__(self):
            return self.title
    

    我希望按投票总数排序,以便在循环访问数据库时,结果按投票总数排序。

    {% extends 'base.html' %}
    
    {% block content %}
    
    {% for product in products.all %}
    <div class="row pt-3">
      <div class="col-2" onclick="window.location='{% url 'detail' product.id %}';" style="cursor:pointer">
        <img src="{{ product.icon.url }}" class="img-fluid" alt="">
      </div>
      <div class="col-6" onclick="window.location='{% url 'detail' product.id %}';" style="cursor:pointer">
        <h1>{{ product.title }}</h1>
        <p>{{ product.summary }}</p>
      </div>
      <div class="col-4" onclick="window.location='{% url 'detail' product.id %}';" style="cursor:pointer">
        <a href="javascript:{document.getElementById('upvote{{ product.id }}').submit()}"><button class="btn btn-primary btn-lg btn-block"><span class="oi oi-caret-top"></span> Upvote {{ product.votes_total }}</button></a>
      </div>
    </div>
    
    <form id="upvote{{ product.id }}" method="POST" action="{% url 'upvote' product.id %}">
      {% csrf_token %}
      <input type="hidden">
    </form>
    {% endfor %}
    
    {% endblock %}
    

    如何对结果排序?

    2 回复  |  直到 7 年前
        1
  •  1
  •   willeM_ Van Onsem    7 年前

    基本上有两种方法可以做到这一点:

    1. 在中定义排序 看法 或;或
    2. 定义 违约 模型

    最后一个选项通常用于模型具有感官(固有)排序的情况(例如,以某种方式对查询集进行排序是非常合乎逻辑的,而且只是偶尔以另一种方式排序)。

    在A中排序 看法

    我们可以使用 .order_by(..) 查询集的函数。函数接受任意数量的参数:指定列名的字符串。如果列名称的前缀是减号( - )这意味着我们按降序排序。

    例如,我们可以定义一个视图:

    def some_view(request):
        my_products = Product.objects.all().order_by('-votes_total')
        return render(request, 'my_template.html', {'my_products': my_products})

    那么我们可以用这个 'my_products' 变量,并对其进行迭代:

    {% extends 'base.html' %}
    
    {% block content %}
    
    {% for product in my_products %}
    <div class="row pt-3">
      <div class="col-2" onclick="window.location='{% url 'detail' product.id %}';" style="cursor:pointer">
        <img src="{{ product.icon.url }}" class="img-fluid" alt="">
      </div>
      <div class="col-6" onclick="window.location='{% url 'detail' product.id %}';" style="cursor:pointer">
        <h1>{{ product.title }}</h1>
        <p>{{ product.summary }}</p>
      </div>
      <div class="col-4" onclick="window.location='{% url 'detail' product.id %}';" style="cursor:pointer">
        <a href="javascript:{document.getElementById('upvote{{ product.id }}').submit()}"><button class="btn btn-primary btn-lg btn-block"><span class="oi oi-caret-top"></span> Upvote {{ product.votes_total }}</button></a>
      </div>
    </div>
    
    <form id="upvote{{ product.id }}" method="POST" action="{% url 'upvote' product.id %}">
      {% csrf_token %}
      <input type="hidden">
    </form>
    {% endfor %}
    
    {% endblock %}

    模型

    如果从模型的角度来看,某种排序是非常合乎逻辑的,那么我们也可以将排序封装到模型本身中。我们用 ordering 的属性 Meta 属性的类。如果我们想订购 Product.objects.all() 默认为中的投票数 降序 订单,我们可以写:

    class Product(models.Model):
    
        title = models.CharField(max_length=200)
        pub_date = models.DateTimeField()
        body = models.TextField()
        url = models.TextField()
        image = models.ImageField(upload_to='images/')
        icon = models.ImageField(upload_to='images/')
        votes_total = models.IntegerField(default=1)
        hunter = models.ForeignKey(User, on_delete=models.CASCADE)
    
        class Meta:
            ordering = ['-votes_total']

    所以现在我们仍然可以访问 Product.objects.all 在模板中,项目将自动排序。

    但是请注意,对于每个模型,我们只能定义一个这样的顺序,因此不能基于特定的视图指定特定的决策。如果要“覆盖”排序,则需要用户 order_by 在查询集上。

        2
  •  3
  •   SHIVAM JINDAL    7 年前

    你应该把 queryset 在您的视图中,并将其传递给模板。按升序排序

    return render(request, template_name,{
        'products': Product.objects.all().order_by('votes_total')
    })
    

    按降序排序:

    return render(request, template_name,{
        'products': Product.objects.all().order_by('-votes_total')
    })
    

    你应该使用 products (不是products.all)在模板中。