相关疑难解决方法(0)

如何在Django中使用SELECT MAX?

我有一个对象列表如何运行查询以给出字段的最大值:

我正在使用此代码:

def get_best_argument(self):
    try:
        arg = self.argument_set.order_by('-rating')[0].details
    except IndexError:
        return 'no posts'
    return arg
Run Code Online (Sandbox Code Playgroud)

rating是一个整数

django max django-models

75
推荐指数
5
解决办法
9万
查看次数

使用子查询来注释计数

请帮助我,我已经被困在这个问题上太久了:(

我想做的事:

我有这两个模型:

class Specialization(models.Model):
    name = models.CharField("name", max_length=64)
class Doctor(models.Model):
    name = models.CharField("name", max_length=128)
    # ...
    specialization = models.ForeignKey(Specialization)
Run Code Online (Sandbox Code Playgroud)

我想用具有该专业的医生数量来注释查询集中的所有专业。

到目前为止我的解决方案:

我经历了一个循环并做了一个简单的: Doctor.objects.filter(specialization=spec).count()然而事实证明这太慢而且效率低下。我读得越多,就越意识到使用此处SubQuery来筛选专业化的医生是有意义的OuterRef。这就是我想出的:

doctors = Doctor.objects.all().filter(specialization=OuterRef("id")) \
    .values("specialization_id") \
    .order_by()
add_doctors_count = doctors.annotate(cnt=Count("specialization_id")).values("cnt")[:1]

spec_qs_with_counts = Specialization.objects.all().annotate(
    num_applicable_doctors=Subquery(add_doctors_count, output_field=IntegerField())
)
Run Code Online (Sandbox Code Playgroud)

对于每个专业,我得到的输出仅为 1。代码只是用它来注释每个医生对象specialization_id,然后注释该组内的计数,这意味着它将是 1。

不幸的是,这对我来说并不完全有意义。在我最初的尝试中,我使用了一个聚合来进行计数,虽然它可以单独工作,但它不能作为 a 工作SubQuery,但我收到此错误:

This queryset contains a reference to an outer query and may only be used in a subquery.

我之前发布过这个问题,有人建议这样做Specialization.objects.annotate(count=Count("doctor"))

然而,这不起作用,因为我需要计算特定的医生查询集。

我已关注这些链接

但是,我没有得到相同的结果:

python django django-aggregation django-annotate django-subquery

10
推荐指数
2
解决办法
2万
查看次数

带有聚合的 Django 子查询

我有两个模型称为UserTransaction。在这里,我想获取状态为成功的交易金额总和的所有用户。

我已尝试使用子查询,但我不知道如何使用条件注释子查询的聚合

class User(models.Model):
  name = models.CharField(max_length=128)

class Transaction(models.Model):
  user = models.ForeignKey(User)
  status = models.CharField(choices=(("success", "Success"),("failed", "Failed")))
   amount = models.DecimalField(max_digits=10, decimal_places=2)

subquery = Transaction.objects.filter(status="success", user=OuterRef('pk')).aggregate(total_spent = Coalesce(Sum('amount'), 0))

query = User.objects.annotate(total_spent=Subquery(subquery:how to do here ?)).order_by(how to order here by total_spent)
Run Code Online (Sandbox Code Playgroud)

django

9
推荐指数
3
解决办法
6692
查看次数

Django条件子查询聚合

我的模型结构的简化示例是

class Corporation(models.Model):
    ...

class Division(models.Model):
    corporation = models.ForeignKey(Corporation)

class Department(models.Model):
    division = models.ForeignKey(Division)
    type = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)

现在我想显示一个表格,显示公司,其中列将包含某种类型的部门数量,例如type=10.目前,这是通过Corporation模型上的帮助程序实现的,例如,检索那些帮助程序

class Corporation(models.Model):
    ...
    def get_departments_type_10(self):
        return (
            Department.objects
            .filter(division__corporation=self, type=10)
            .count()
        )
Run Code Online (Sandbox Code Playgroud)

这里的问题是,由于N + 1问题,这绝对是谋杀性能.

我试图用接近这个问题select_related,prefetch_related,annotate,和subquery,但我没有带能够得到我需要的结果.

理想情况下,查询Corporation集中的每个应该使用一个整数进行注释,该整数type_10_count反映了该类型的部门数量.

我确信我可以用原始sql做一些事情.extra(),但是文档宣布它将被弃用(我在Django 1.11上)

编辑:原始sql解决方案的示例

corps = Corporation.objects.raw("""
SELECT
*,
(
    SELECT COUNT(*)
    FROM foo_division div ON div.corporation_id = c.id
    JOIN foo_department dept ON dept.division_id = div.id
    WHERE dept.type …
Run Code Online (Sandbox Code Playgroud)

django django-annotate django-subquery

6
推荐指数
1
解决办法
1832
查看次数

Django QuerySet:用于计数值出现次数的附加字段

我有一个包含 100 个项目的对象,对于每个项目,我需要知道特定内容在该字段中出现的QuerySet次数。contract_numbercontract_number

预期输出示例:

[{'contract_number': 123, 'contract_count': 2}, {'contract_number': 456, 'contract_count': 1} ...]
Run Code Online (Sandbox Code Playgroud)

这意味着值 123 在整个contract_number字段中出现了 2 次。

重要的是:我无法减少项目的数量,因此分组在这里不起作用。

与此等效的 SQL 将是一个附加字段,contract_count如下所示:

 SELECT *,
 (SELECT count(contract_number) FROM table where t.contract_number = contract_number) as contract_count
FROM table as t
Run Code Online (Sandbox Code Playgroud)

问题是如何使用 Python 对象来做到这一点。经过一些研究,我发现对于更复杂的查询,应该使用Queryset 额外方法。以下是我的尝试之一,但结果不是我所期望的

    queryset = Tracker.objects.extra(
    select={
        'contract_count': '''
        SELECT COUNT(*)
        FROM table
        WHERE contract_number = %s
        '''
    },select_params=(F('contract_number'),),)
Run Code Online (Sandbox Code Playgroud)

我的models.py

class Tracker(models.Model):
    contract_number = models.IntegerField()
Run Code Online (Sandbox Code Playgroud)

编辑: 我的问题的解决方案是Subquery()

python sql django django-queryset extra

4
推荐指数
1
解决办法
1316
查看次数

Django ORM 在注释多个聚合列时删除不需要的组

我想在 django ORM 中创建一个类似这样的查询。

SELECT COUNT(CASE WHEN myCondition THEN 1 ELSE NULL end) as numyear
FROM myTable
Run Code Online (Sandbox Code Playgroud)

以下是我编写的 djang ORM 查询

year_case = Case(When(added_on__year = today.year, then=1), output_field=IntegerField())

qs = (ProfaneContent.objects
                    .annotate(numyear=Count(year_case))
                    .values('numyear'))
Run Code Online (Sandbox Code Playgroud)

这是由 django orm 生成的查询。

SELECT COUNT(CASE WHEN "analyzer_profanecontent"."added_on" BETWEEN 2020-01-01 00:00:00+00:00 AND 2020-12-31 23:59:59.999999+00:00 THEN 1 ELSE NULL END) AS "numyear" FROM "analyzer_profanecontent" GROUP BY "analyzer_profanecontent"."id"
Run Code Online (Sandbox Code Playgroud)

所有其他事情都很好,但是 django在最后放置了一个GROUP BY导致多行和错误答案。我根本不想那样。现在只有一列,但我会放置更多这样的列。

根据评论进行编辑 我将使用 qs 变量来获取我的分类在当前年、月、周的值。

更新 根据我来到这里的评论和答案,让我澄清一下。我只想在数据库端执行此操作(显然使用 Django ORM 而不是 RAW SQL)。它是一个简单的 sql 查询。由于数据可能太大,在 Python 端做任何事情都是低效的。这就是为什么我希望数据库根据 CASE …

sql django orm django-models django-orm

3
推荐指数
1
解决办法
690
查看次数

注释另一个模型中字段值出现的计数

使用 Django 1.11。这些是我的模型:

class UserPromoCode(models.Model):
    promo_code = models.ForeignKey(PromoCode, related_name="user_promo_code")

class PromoCode(models.Model):
    code = models.CharField(max_length=20)
Run Code Online (Sandbox Code Playgroud)

我需要一个查询集,在一个或两个数据库请求中执行以下操作:

promocodes = PromoCode.objects.all()
for p in promocodes:
   p.assigned_times = UserPromoCode.objects.filter(promo_code__code=p.code).count()
Run Code Online (Sandbox Code Playgroud)

问题是 PromoCode.code 不是唯一的,所以我不能做PromoCode.objects.annontate(assigned_times=Count('user_promo_code'))以下类似的事情:

promocodes = PromoCode.objects.all()
for p in promocodes:
   p.assigned_times = p.user_promo_code.count()
Run Code Online (Sandbox Code Playgroud)

我想它应该是类似 PromoCode.objects.annontate(assigned_times=Count(???)) 的东西。

python django annotations

1
推荐指数
1
解决办法
1708
查看次数