Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
5e1f4656
Kaydet (Commit)
5e1f4656
authored
Nis 28, 2014
tarafından
Anssi Kääriäinen
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #22429 -- Incorrect SQL when using ~Q and F
üst
13ec89f2
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
50 additions
and
10 deletions
+50
-10
query.py
django/db/models/sql/query.py
+16
-9
1.6.5.txt
docs/releases/1.6.5.txt
+3
-0
models.py
tests/queries/models.py
+15
-0
tests.py
tests/queries/tests.py
+16
-1
No files found.
django/db/models/sql/query.py
Dosyayı görüntüle @
5e1f4656
...
...
@@ -1159,6 +1159,9 @@ class Query(object):
try
:
field
,
sources
,
opts
,
join_list
,
path
=
self
.
setup_joins
(
parts
,
opts
,
alias
,
can_reuse
,
allow_many
)
# split_exclude() needs to know which joins were generated for the
# lookup parts
self
.
_lookup_joins
=
join_list
except
MultiJoin
as
e
:
return
self
.
split_exclude
(
filter_expr
,
LOOKUP_SEP
.
join
(
parts
[:
e
.
level
]),
can_reuse
,
e
.
names_with_path
)
...
...
@@ -1899,17 +1902,21 @@ class Query(object):
for
_
,
paths
in
names_with_path
:
all_paths
.
extend
(
paths
)
contains_louter
=
False
for
pos
,
path
in
enumerate
(
all_paths
):
# Trim and operate only on tables that were generated for
# the lookup part of the query. That is, avoid trimming
# joins generated for F() expressions.
lookup_tables
=
[
t
for
t
in
self
.
tables
if
t
in
self
.
_lookup_joins
or
t
==
self
.
tables
[
0
]]
for
trimmed_paths
,
path
in
enumerate
(
all_paths
):
if
path
.
m2m
:
break
if
self
.
alias_map
[
self
.
tables
[
po
s
+
1
]]
.
join_type
==
self
.
LOUTER
:
if
self
.
alias_map
[
lookup_tables
[
trimmed_path
s
+
1
]]
.
join_type
==
self
.
LOUTER
:
contains_louter
=
True
self
.
unref_alias
(
self
.
tables
[
po
s
])
self
.
unref_alias
(
lookup_tables
[
trimmed_path
s
])
# The path.join_field is a Rel, lets get the other side's field
join_field
=
path
.
join_field
.
field
# Build the filter prefix.
paths_in_prefix
=
trimmed_paths
trimmed_prefix
=
[]
paths_in_prefix
=
pos
for
name
,
path
in
names_with_path
:
if
paths_in_prefix
-
len
(
path
)
<
0
:
break
...
...
@@ -1921,12 +1928,12 @@ class Query(object):
# Lets still see if we can trim the first join from the inner query
# (that is, self). We can't do this for LEFT JOINs because we would
# miss those rows that have nothing on the outer side.
if
self
.
alias_map
[
self
.
tables
[
po
s
+
1
]]
.
join_type
!=
self
.
LOUTER
:
if
self
.
alias_map
[
lookup_tables
[
trimmed_path
s
+
1
]]
.
join_type
!=
self
.
LOUTER
:
select_fields
=
[
r
[
0
]
for
r
in
join_field
.
related_fields
]
select_alias
=
self
.
tables
[
po
s
+
1
]
self
.
unref_alias
(
self
.
tables
[
po
s
])
select_alias
=
lookup_tables
[
trimmed_path
s
+
1
]
self
.
unref_alias
(
lookup_tables
[
trimmed_path
s
])
extra_restriction
=
join_field
.
get_extra_restriction
(
self
.
where_class
,
None
,
self
.
tables
[
po
s
+
1
])
self
.
where_class
,
None
,
lookup_tables
[
trimmed_path
s
+
1
])
if
extra_restriction
:
self
.
where
.
add
(
extra_restriction
,
AND
)
else
:
...
...
@@ -1934,7 +1941,7 @@ class Query(object):
# inner query if it happens to have a longer join chain containing the
# values in select_fields. Lets punt this one for now.
select_fields
=
[
r
[
1
]
for
r
in
join_field
.
related_fields
]
select_alias
=
self
.
tables
[
po
s
]
select_alias
=
lookup_tables
[
trimmed_path
s
]
self
.
select
=
[
SelectInfo
((
select_alias
,
f
.
column
),
f
)
for
f
in
select_fields
]
return
trimmed_prefix
,
contains_louter
...
...
docs/releases/1.6.5.txt
Dosyayı görüntüle @
5e1f4656
...
...
@@ -14,3 +14,6 @@ Bugfixes
* Fixed ``pgettext_lazy`` crash when receiving bytestring content on Python 2
(`#22565 <http://code.djangoproject.com/ticket/22565>`_).
* Fixed the SQL generated when filtering by a negated ``Q`` object that contains
a ``F`` object. (`#22429 <http://code.djangoproject.com/ticket/22429>`_).
tests/queries/models.py
Dosyayı görüntüle @
5e1f4656
...
...
@@ -660,3 +660,18 @@ class Employment(models.Model):
employer
=
models
.
ForeignKey
(
Company
)
employee
=
models
.
ForeignKey
(
Person
)
title
=
models
.
CharField
(
max_length
=
128
)
# Bug #22429
class
School
(
models
.
Model
):
pass
class
Student
(
models
.
Model
):
school
=
models
.
ForeignKey
(
School
)
class
Classroom
(
models
.
Model
):
school
=
models
.
ForeignKey
(
School
)
students
=
models
.
ManyToManyField
(
Student
,
related_name
=
'classroom'
)
tests/queries/tests.py
Dosyayı görüntüle @
5e1f4656
...
...
@@ -28,7 +28,7 @@ from .models import (
BaseA
,
FK1
,
Identifier
,
Program
,
Channel
,
Page
,
Paragraph
,
Chapter
,
Book
,
MyObject
,
Order
,
OrderItem
,
SharedConnection
,
Task
,
Staff
,
StaffUser
,
CategoryRelationship
,
Ticket21203Parent
,
Ticket21203Child
,
Person
,
Company
,
Employment
,
CustomPk
,
CustomPkTag
)
Company
,
Employment
,
CustomPk
,
CustomPkTag
,
Classroom
,
School
,
Student
)
class
BaseQuerysetTest
(
TestCase
):
...
...
@@ -3345,3 +3345,18 @@ class ReverseM2MCustomPkTests(TestCase):
self
.
assertQuerysetEqual
(
CustomPkTag
.
objects
.
filter
(
custom_pk
=
cp1
),
[
cpt1
],
lambda
x
:
x
)
class
Ticket22429Tests
(
TestCase
):
def
test_ticket_22429
(
self
):
sc1
=
School
.
objects
.
create
()
st1
=
Student
.
objects
.
create
(
school
=
sc1
)
sc2
=
School
.
objects
.
create
()
st2
=
Student
.
objects
.
create
(
school
=
sc2
)
cr
=
Classroom
.
objects
.
create
(
school
=
sc1
)
cr
.
students
.
add
(
st1
)
queryset
=
Student
.
objects
.
filter
(
~
Q
(
classroom__school
=
F
(
'school'
)))
self
.
assertQuerysetEqual
(
queryset
,
[
st2
],
lambda
x
:
x
)
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment