我有一个Booking有start和enddatetime字段的模型.我想知道预订的天数.我可以在Python中执行此操作,但我需要此值以进行进一步注释.
这是我尝试过的:
In [1]: Booking.objects.annotate(days=F('end')-F('start'))[0].days
Out[1]: datetime.timedelta(16, 50400)
Run Code Online (Sandbox Code Playgroud)
这里有一些问题:
在Python中,我会这样做(end.date() - start.date()).days + 1.我怎样才能在数据库中做到这一点,最好是通过ORM(例如数据库函数),但是RawSQL这样就足以让它出门了?
我想根据不区分大小写的字段值获取所有重复项。
基本上重写这个SQL查询
SELECT count(*), lower(name)
FROM manufacturer
GROUP BY lower(name)
HAVING count(*) > 1;
Run Code Online (Sandbox Code Playgroud)
使用 Django ORM。我希望这样的事情可以解决问题
from django.db.models import Count
from django.db.models.functions import Lower
from myapp.models import Manufacturer
qs = Manufacturer.objects.annotate(
name_lower=Lower('name'),
cnt=Count('name_lower')
).filter('cnt__gt'=1)
Run Code Online (Sandbox Code Playgroud)
但当然它没有用。
知道如何做到这一点吗?
我有一个名为的模型Post,它有两个字段upvotes和downvotes. 现在upvotes,downvotes是ManyToManyField到Profile。这是模型:
class Post(models.Model):
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
title = models.CharField(max_length=300)
content = models.CharField(max_length=1000)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
subreddit = models.ForeignKey(Subreddit, on_delete=models.CASCADE)
upvotes = models.ManyToManyField(Profile, blank=True, related_name='upvoted_posts')
downvotes = models.ManyToManyField(Profile, blank=True, related_name='downvoted_posts')
Run Code Online (Sandbox Code Playgroud)
所以,我想获取所有帖子,使它们按以下顺序排列
total(upvotes) - total(downvotes)
所以我使用了这个查询:
Post.objects.annotate(
total_votes=Count('upvotes')-Count('downvotes')
).order_by('total_votes')
Run Code Online (Sandbox Code Playgroud)
此查询的问题total_votes是结果总是为零。
以下查询将解释这种情况:
In [5]: Post.objects.annotate(up=Count('upvotes')).values('up')
Out[5]: <QuerySet [{'up': 1}, {'up': 3}, {'up': 2}]>
In [6]: Post.objects.annotate(down=Count('downvotes')).values('down')
Out[6]: <QuerySet [{'down': 1}, …Run Code Online (Sandbox Code Playgroud) 我有一个 Django 应用程序,具有以下模型:
class Person(models.Model):
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Job(models.Model):
title = models.CharField(max_length=100)
class PersonJob(models.Model):
person = models.ForeignKey(Person, related_name='person_jobs')
job = models.ForeignKey(Job, related_name='person_jobs')
is_active = models.BooleanField()
Run Code Online (Sandbox Code Playgroud)
多个Person实例可以同时承担相同的工作。我有一个Job查询集,并尝试注释或通过其他方法将从事该工作的每个人的姓名附加到查询集中的每个项目上。我希望能够循环查询集并获取这些名称,而无需对每个项目进行额外的查询。我得到的最接近的是:
qs = Job.objects.all().annotate(first_names='person_jobs__person__first_name')
.annotate(last_names='person_jobs__person__last_name')
Run Code Online (Sandbox Code Playgroud)
这将按照我的意愿将名称存储在 Job 实例上;但是,如果一个作业中有多个人员,则查询集中将包含同一作业的多个副本,每个副本都有一个人的姓名。相反,我只需要查询集中给定作业的一个实例,该实例包含其中所有人员的姓名。我不关心这些值是如何组合和存储的;列表、分隔字符字段或任何其他标准数据类型都可以。
我正在使用 Django 2.1 和 Postgres 10.3。我强烈希望不使用任何 Postgres 特定功能。
我的问题如下。有一个请求
Thread.objects.all().annotate(is_marked=Count('mark', Q(mark__username='gou')))
在 SQL 中它看起来像这样
SELECT "api_thread"."id",
"api_thread"."conference_id",
"api_thread"."title",
"api_thread"."description",
"api_thread"."is_closed",
"api_thread"."is_hidden",
"api_thread"."is_pinned",
"api_thread"."has_voting",
"api_thread"."creator_uid",
"api_thread"."created_at",
"api_thread"."expired",
COUNT("api_thread_mark"."user_id") FILTER (WHERE "auth_user"."username" = 'gou') AS "is_marked"
FROM "api_thread"
LEFT OUTER JOIN "api_thread_mark" ON ("api_thread"."id" = "api_thread_mark"."thread_id")
LEFT OUTER JOIN "auth_user" ON ("api_thread_mark"."user_id" = "auth_user"."id")
GROUP BY "api_thread"."id"
Run Code Online (Sandbox Code Playgroud)
我需要做什么才能将数字转换为布尔值。在 SQL 中它看起来像
COUNT("api_thread_mark"."user_id") FILTER (WHERE "auth_user"."username" = 'gou') > 0 AS "is_marked"
Run Code Online (Sandbox Code Playgroud) django postgresql django-orm django-queryset django-annotate
我有两个模型诊所和诊所信用:我想要一个诊所列表和可用余额的总和问题是如果我使用注释,我必须循环使用诊所信用查询集:
class Clinic(models.Model):
"""
clinic model
"""
user = models.OneToOneField(User, related_name="clinic", primary_key=True,
on_delete=models.CASCADE)
def __str__(self):
return self.name
class Meta:
db_table = 'clinic'
class ClinicCredits(models.Model):
"""
credit details for clinic
"""
clinic = models.ForeignKey(Clinic, on_delete=models.CASCADE, related_name='c_credits')
credits = models.FloatField('credits', default=0.0)
balance = models.FloatField('balance', default=0.0, help_text="balance after deduction of credits")
def __str__(self):
return self.clinic.name
class Meta:
db_table = 'clinic_credits'
Run Code Online (Sandbox Code Playgroud)
这是我获取诊所的查询:
clinics = Clinic.objects.filter(practice_id__in=user.dietitian.practiceid).order_by(
'user__date_joined').prefetch_related(Prefetch('c_credits',ClinicCredits.objects.filter(balance__gt=0),'credit_'))
Run Code Online (Sandbox Code Playgroud)
以及我如何在这种情况下使用聚合,或者是否有其他方法可以使用可用积分来检索诊所列表。
Demand我有一个对象列表,这些对象的allocated字段要么是名称null,要么有一个名称(表示此需求的分配)。
我使用注释来计算每个团队已分配/未分配的数量:
Demand.objects.filter(project=project).values('team').annotate(
unallocated=Count('allocated', filter=Q(allocated__isnull=True)),
allocated=Count('allocated', filter=Q(allocated__isnull=False))
)
Run Code Online (Sandbox Code Playgroud)
奇怪的是,注释的数字allocated显示正确,但 的数字unallocated始终为零。
例如:
list(Demand.objects.filter(project=project).values('allocated', 'team'))
Run Code Online (Sandbox Code Playgroud)
结果如下:
[{'allocated': None, 'team': 'Design'},
{'allocated': None, 'team': 'Engineering'},
{'allocated': None, 'team': 'Engineering'},
{'allocated': None, 'team': 'Engineering'},
{'allocated': None, 'team': 'Delivery'},
{'allocated': None, 'team': 'Product'}]
Run Code Online (Sandbox Code Playgroud)
但注释只有这样:
<QuerySet
[{'team': 'Delivery', 'unallocated': 0, 'allocated': 0},
{'team': 'Design', 'unallocated': 0, 'allocated': 0},
{'team': 'Engineering', 'unallocated': 0, 'allocated': 0},
{'team': 'Product', 'unallocated': 0, 'allocated': 0}]>
Run Code Online (Sandbox Code Playgroud)
我做错了吗?或者这可能是一个错误?
我有我需要得到所有对象,其中使用案例existing_field是开始some string。
some string 动态变化,所以我需要一种聪明的方法来过滤掉对象。
我的想法是像这样创建带注释的查询:
MyModel.objects.annotate(annotated_field='some string').filter(annotated_field__startswith=F('existing_field'))
Run Code Online (Sandbox Code Playgroud)
目前它失败了:
QuerySet.annotate() received non-expression(s): some string
有没有办法用字符串值注释对象?
我在我的项目中使用了 postgresql 数据库,我使用了 django文档中的以下示例。
from django.db.models import OuterRef, Subquery
newest = Comment.objects.filter(post=OuterRef('pk')).order_by('-created_at')
Post.objects.annotate(newest_commenter_email=Subquery(newest.values('email')[:1]))
Run Code Online (Sandbox Code Playgroud)
但不是最新的评论者电子邮件,我需要最后两封评论者的电子邮件。我改变了[:1]对[:2],但此异常引发:ProgrammingError: more than one row returned by a subquery used as an expression。
django django-orm django-postgresql django-annotate django-subquery
我有一个查询,如下所示,该查询返回特定课程(学年)中特定学期(学期)中特定班级的所有学生的成绩:
grades = Grade.objects.filter(term='First', student__in_class=1,session=1).order_by('-total')
Run Code Online (Sandbox Code Playgroud)
然后是另一个对成绩进行注释的查询,以获取“总计”字段的总和。
grades_ordered = grades.values('student')\
.annotate(total_mark=Sum('total')) \
.order_by('-total_mark')
Run Code Online (Sandbox Code Playgroud)
最初,一切正常,直到我从使用SQLite迁移到PostgreSQL时,以下错误开始出现。
错误:
function sum(character varying) does not exist
LINE 1: SELECT "sms_grade"."student_id", SUM("sms_grade"."total") AS...
^
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Run Code Online (Sandbox Code Playgroud)
编辑:这是我的模型
class Grade(models.Model):
session = models.ForeignKey(Session, on_delete=models.CASCADE)
term = models.CharField(choices=TERM, max_length=7)
student = models.ForeignKey(Student, on_delete=models.CASCADE)
subject = models.ForeignKey(Subject, on_delete=models.CASCADE)
fca = models.CharField(max_length=10)
sca = models.CharField(max_length=10)
exam = models.CharField(max_length=10)
total = models.CharField(max_length=3, blank=True, null=True)
grade = …Run Code Online (Sandbox Code Playgroud) django postgresql django-orm django-database django-annotate
django ×10
django-annotate ×10
django-orm ×3
python ×3
postgresql ×2
datetime ×1
django-q ×1
duplicates ×1
foreign-keys ×1
prefetch ×1
python-3.x ×1