说我有一个模型:
class Foo(models.Model):
...
Run Code Online (Sandbox Code Playgroud)
和另一个基本上为每个用户提供以下信息的模型Foo:
class UserFoo(models.Model):
user = models.ForeignKey(User)
foo = models.ForeignKey(Foo)
...
class Meta:
unique_together = ("user", "foo")
Run Code Online (Sandbox Code Playgroud)
我想生成一个Foos的查询集,但注释与(可选)相关的UserFoo基于user=request.user.
所以它实际上是一个 LEFT OUTER JOIN on (foo.id = userfoo.foo_id AND userfoo.user_id = ...)
我有以下型号:
class Volunteer(models.Model):
first_name = models.CharField(max_length=50L)
last_name = models.CharField(max_length=50L)
email = models.CharField(max_length=50L)
gender = models.CharField(max_length=1, choices=GENDER_CHOICES)
class Department(models.Model):
name = models.CharField(max_length=50L, unique=True)
overseer = models.ForeignKey(Volunteer, blank=True, null=True)
location = models.CharField(max_length=100L, null=True)
class DepartmentVolunteer(models.Model):
volunteer = models.ForeignKey(Volunteer)
department = models.ForeignKey(Department)
assistant = models.BooleanField(default=False)
keyman = models.BooleanField(default=False)
captain = models.BooleanField(default=False)
location = models.CharField(max_length=100L, blank=True, null=True)
Run Code Online (Sandbox Code Playgroud)
我想查询没有志愿者分配给他们的所有部门.我可以使用以下查询执行此操作:
SELECT
vsp_department.name
FROM
vsp_department
LEFT JOIN vsp_departmentvolunteer ON vsp_department.id = vsp_departmentvolunteer.department_id
WHERE
vsp_departmentvolunteer.department_id IS NULL;
Run Code Online (Sandbox Code Playgroud)
是否有更像django的方式这样做或者我应该使用原始sql?
我有这三个模型:
class Track(models.Model):
title = models.TextField()
artist = models.TextField()
class Tag(models.Model):
name = models.CharField(max_length=50)
class TrackHasTag(models.Model):
track = models.ForeignKey('Track', on_delete=models.CASCADE)
tag = models.ForeignKey('Tag', on_delete=models.PROTECT)
Run Code Online (Sandbox Code Playgroud)
我想要检索所有未标记特定标记的曲目.这让我得到了我想要的东西:Track.objects.exclude(trackhastag__tag_id='1').only('id')但是当桌子增长时它会很慢.这是我在打印查询.query集时得到的:
SELECT "track"."id"
FROM "track"
WHERE NOT ( "track"."id" IN (SELECT U1."track_id" AS Col1
FROM "trackhastag" U1
WHERE U1."tag_id" = 1) )
Run Code Online (Sandbox Code Playgroud)
我希望Django发送此查询:
SELECT "track"."id"
FROM "track"
LEFT OUTER JOIN "trackhastag"
ON "track"."id" = "trackhastag"."track_id"
AND "trackhastag"."tag_id" = 1
WHERE "trackhastag"."id" IS NULL;
Run Code Online (Sandbox Code Playgroud)
但还没有找到办法.使用原始查询实际上不是一个选项,因为我必须经常过滤生成的查询集.
我已经找到了干净的解决方法是在数据库中创建一个视图和模型TrackHasTagFoo用managed = False,我用它来查询,如:Track.objects.filter(trackhastagfoo__isnull=True) …
如何使用django QuerySet API跨M2M关系芯片创建完整外部联接的查询?
它不受支持,一些提示创建我自己的经理来做这件事将是受欢迎的.
编辑补充: @ S.Lott:感谢您的启发.OUTER JOIN的需求来自应用程序.它必须生成一个报告,显示输入的数据,即使它仍然不完整.我不知道结果将是一个新的类/模型.你的提示会对我有所帮助.
我有一个通过字段Student与模型相关的Course模型ManyToMany:
class Student(Model):
name = TextField()
class Course(Model):
name = TextField()
students = ManyToManyField(Student, through="StudentCourse")
class StudentCourse(Model):
student = ForeignKey(Student)
course = ForeignKey(Course)
section_name = TextField()
Run Code Online (Sandbox Code Playgroud)
如何自动注释通过Course.students多对多字段检索到的学生及其课程中的部分?
例如,不必extra在每个查询上添加显式:
>>> students = course.students.extra(select={
... "section_name": "app_student_course.section_name",
... })
>>> print students[0].section_name
u'First Section'
Run Code Online (Sandbox Code Playgroud)
我只能:
>>> students = course.students.all()
>>> print students[0].section_name
u'First Section'
Run Code Online (Sandbox Code Playgroud)
谢谢!
这是相关代码:
class Book(models.Model):
name = models.CharField(max_length=50)
class BookNote(models.Model):
text = models.CharField(max_length=50)
book = models.ForeignKey(Book)
user = models.ForeignKey(settings.AUTH_USER_MODEL)
class Meta:
unique_together = [('book', 'user'), ]
Run Code Online (Sandbox Code Playgroud)
现在,对于网站中的特定用户:
我想查询所有书籍(所有表格)。并且,
对于每个 book 对象,如果用户有这本书的 BookNote - 获取它,否则 booknote 应该为 null。
这就是我将如何使用 SQL(有效)做到这一点:
SELECT book.name, booknote.text
FROM book
LEFT OUTER JOIN booknote ON
(book.id = booknote.book_id AND booknote.user_id = {user_id_here})
Run Code Online (Sandbox Code Playgroud)
这是我尝试过,也没有工作:
qs = Book.objects.filter(Q(booknote__user_id=user_id_here) | Q(booknote__isnull=True))
Run Code Online (Sandbox Code Playgroud)
我检查了一下qs.query,我明白了为什么 - Django 使用 WHERE 子句来过滤 user_id,所以我没有得到所有的书。
如何使用 django ORM 执行相同的查询?没有原始sql?