Django Order QuerySet by Min Value from Child Table

如何解决Django Order QuerySet by Min Value from Child Table

我正在努力在 Django 中创建一个特定的复杂查询。 我正在使用 pagination 在索引页面上显示蛋糕列表。我想按不同的属性对它们进行排序。下面是我的索引页截图。

index page screenshot

Name (A-Z)Name (Z-A) 是通过简单地按“name”或“-name”对 Cake 查询集进行排序来实现的,我从页面顶部的表单中将其作为 POST 获取。

cakes_list = Cake.objects.all().order_by('name')

但是我正在努力按最低价格订购查询集。 每个蛋糕都有不同的尺寸和不同的价格(蛋糕之间的尺寸和价格不同)。它们存储在 Dimension 中,外键指向它们所属的 Cake。 我想找出每个蛋糕最便宜的选项,并根据它(最低价格升序和降序)订购我在分页中使用的蛋糕列表。

我还创建了一个方法 from_price 来返回那个蛋糕的价格。我在模板中使用它来显示每个蛋糕的名称和最低价格。但我似乎无法将其实施到我的排序中。

我很感激有关如何创建查询或类似问题的帮助,让我可以根据每个蛋糕的最低价格对所有蛋糕进行排序。我只是在学习 Django,所以我目前的实现可能并不理想。

保险库/models.py:

class Cake(models.Model):
    name = models.CharField(max_length=200)

    def from_price(self):
        temp = self.dimension_set.aggregate(Min('price')).get('price__min')
        if not temp:
            temp = 0
        return temp

class Dimension(models.Model):
    cake = models.ForeignKey(Cake,on_delete=models.CASCADE)
    dimension = models.CharField(max_length=50)
    price = models.DecimalField(max_digits=6,decimal_places=2)

保险库/views.py

def index(request):
    #from the form on the index page
    order_by = request.POST.get('order_by')
    if not order_by:
        order_by = 'name'

    cakes_list = Cake.objects.all().order_by(order_by)
    paginator = Paginator(cakes_list,5)

    page_number = request.GET.get('page',1)
    page_obj = paginator.get_page(page_number)
    return render(request,'vault/index.html',{'page_obj': page_obj,'order_by': order_by})


Vault/templates/vault/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

{# Form for cake sorting dropdown #}
<form action="{% url 'vault:index' %}" method="post">
    {% csrf_token %}
    <label for="order_by">Order by:</label>
    <select name="order_by" id="order_by">
        <option {% if order_by == "name" %} selected="selected" {% endif %} value="name">Name (A-Z)</option>
        <option {% if order_by == "-name" %} selected="selected" {% endif %} value="-name">Name (Z-A)</option>
        {% comment %}
        New options for ordering by price
        <option {% if order_by == "" %} selected="selected" {% endif %} value="name">Price from (Low to High)</option>
        <option {% if order_by == "" %} selected="selected" {% endif %} value="-name">Price from (High to Low)</option>
        {% endcomment %}
    </select>
    <input type="submit" value="Select">
</form>

{# Code for printing the list of cakes #}
{% if page_obj %}
    <ul>
        {% for cake in page_obj %}
            <li>
                <a href="{% url 'vault:detail' cake.id %}">
                    {{ cake.name }}
                    {% if cake.from_price %}
                        - from &#163;{{ cake.from_price|floatformat:'2' }}
                    {% endif %}
                </a>
            </li>
        {% endfor %}
    </ul>
{% else %}
    <p>No cakes are available</p>
{% endif %}

{# Code for the pagination navigation elements #}
<div class="pagination">
    <span class="step-links">
        {% if page_obj.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ page_obj.previous_page_number }}">previous</a>
        {% endif %}
        <span class="current">
            Page {{  page_obj.number }} of {{ page_obj.paginator.num_pages }}.
        </span>

        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">next</a>
            <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>

</div>
</body>
</html>

解决方法

在这样排序之前尝试使用注释:

cakes_list = Cake.objects.annotate(
    max_price=Max('dimension__price'),).order_by('max_price')
,

如果您需要每个 Cake 记录的最低价格值,那么最简单的方法可能是使用 subquery

from django.db.models import OuterRef,Subquery

sub_q = Dimension.objects.filter(cake=OuterRef('id')).order_by('price')
qs = Cake.objects.annotate(min_price=Subquery(sub_q.values('prize')[:1]).order_by('min_price')

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-