Exemplo n.º 1
0
    def test_q_object_or(self):
        """
        SQL query parameters for generic relations are properly
        grouped when OR is used (#11535).

        In this bug the first query (below) works while the second, with the
        query parameters the same but in reverse order, does not.

        The issue is that the generic relation conditions do not get properly
        grouped in parentheses.
        """
        note_contact = Contact.objects.create()
        org_contact = Contact.objects.create()
        Note.objects.create(note='note', content_object=note_contact)
        org = Organization.objects.create(name='org name')
        org.contacts.add(org_contact)
        # search with a non-matching note and a matching org name
        qs = Contact.objects.filter(
            Q(notes__note__icontains=r'other note')
            | Q(organizations__name__icontains=r'org name'))
        self.assertIn(org_contact, qs)
        # search again, with the same query parameters, in reverse order
        qs = Contact.objects.filter(
            Q(organizations__name__icontains=r'org name')
            | Q(notes__note__icontains=r'other note'))
        self.assertIn(org_contact, qs)
Exemplo n.º 2
0
 def test_related_aggregates_m2m_and_fk(self):
     q = Q(friends__book__publisher__name='Apress') & ~Q(
         friends__name='test3')
     agg = Sum('friends__book__pages', filter=q)
     self.assertEqual(
         Author.objects.filter(name='test').aggregate(pages=agg)['pages'],
         528)
Exemplo n.º 3
0
 def test_difference(self):
     qs1 = Author.objects.annotate(
         book_alice=FilteredRelation('book', condition=Q(book__title__iexact='poem by alice')),
     ).filter(book_alice__isnull=False)
     qs2 = Author.objects.annotate(
         book_jane=FilteredRelation('book', condition=Q(book__title__iexact='the book by jane a')),
     ).filter(book_jane__isnull=False)
     self.assertSequenceEqual(qs1.difference(qs2), [self.author1])
Exemplo n.º 4
0
 def test_empty_in(self):
     # Passing "in" an empty list returns no results ...
     self.assertQuerysetEqual(Article.objects.filter(pk__in=[]), [])
     # ... but can return results if we OR it with another query.
     self.assertQuerysetEqual(
         Article.objects.filter(
             Q(pk__in=[]) | Q(headline__icontains='goodbye')),
         ['Goodbye', 'Hello and goodbye'],
         attrgetter("headline"),
     )
Exemplo n.º 5
0
    def test_empty_expression_annotation(self):
        books = Book.objects.annotate(selected=ExpressionWrapper(
            Q(pk__in=[]), output_field=BooleanField()))
        self.assertEqual(len(books), Book.objects.count())
        self.assertTrue(all(not book.selected for book in books))

        books = Book.objects.annotate(selected=ExpressionWrapper(
            Q(pk__in=Book.objects.none()), output_field=BooleanField()))
        self.assertEqual(len(books), Book.objects.count())
        self.assertTrue(all(not book.selected for book in books))
Exemplo n.º 6
0
 def test_deconstruct_or(self):
     q1 = Q(price__gt=F('discounted_price'))
     q2 = Q(price=F('discounted_price'))
     q = q1 | q2
     path, args, kwargs = q.deconstruct()
     self.assertEqual(args, (
         ('price__gt', F('discounted_price')),
         ('price', F('discounted_price')),
     ))
     self.assertEqual(kwargs, {'_connector': 'OR'})
Exemplo n.º 7
0
 def test_deconstruct_and(self):
     q1 = Q(price__gt=F('discounted_price'))
     q2 = Q(price=F('discounted_price'))
     q = q1 & q2
     path, args, kwargs = q.deconstruct()
     self.assertEqual(args, (
         ('price__gt', F('discounted_price')),
         ('price', F('discounted_price')),
     ))
     self.assertEqual(kwargs, {})
Exemplo n.º 8
0
    def test_pk_q(self):
        self.assertQuerysetEqual(
            Article.objects.filter(Q(pk=self.a1) | Q(pk=self.a2)),
            ['Hello', 'Goodbye'], attrgetter("headline"))

        self.assertQuerysetEqual(
            Article.objects.filter(
                Q(pk=self.a1) | Q(pk=self.a2) | Q(pk=self.a3)),
            ['Hello', 'Goodbye', 'Hello and goodbye'],
            attrgetter("headline"),
        )
Exemplo n.º 9
0
 def test_with_join_and_complex_condition(self):
     self.assertSequenceEqual(
         Author.objects.annotate(
             book_alice=FilteredRelation(
                 'book', condition=Q(
                     Q(book__title__iexact='poem by alice') |
                     Q(book__state=Book.RENTED)
                 ),
             ),
         ).filter(book_alice__isnull=False),
         [self.author1]
     )
Exemplo n.º 10
0
    def test_query_content_object(self):
        qs = TaggedItem.objects.filter(animal__isnull=False).order_by(
            'animal__common_name', 'tag')
        self.assertQuerysetEqual(
            qs, ["<TaggedItem: hairy>", "<TaggedItem: yellow>"])

        mpk = ManualPK.objects.create(id=1)
        mpk.tags.create(tag='mpk')
        qs = TaggedItem.objects.filter(
            Q(animal__isnull=False) | Q(manualpk__id=1)).order_by('tag')
        self.assertQuerysetEqual(qs, ["hairy", "mpk", "yellow"],
                                 lambda x: x.tag)
Exemplo n.º 11
0
    def test_m2m_and_m2o(self):
        r = User.objects.create(username="******")
        g = User.objects.create(username="******")

        i1 = Issue(num=1)
        i1.client = r
        i1.save()

        i2 = Issue(num=2)
        i2.client = r
        i2.save()
        i2.cc.add(r)

        i3 = Issue(num=3)
        i3.client = g
        i3.save()
        i3.cc.add(r)

        self.assertQuerysetEqual(Issue.objects.filter(client=r.id), [
            1,
            2,
        ], lambda i: i.num)
        self.assertQuerysetEqual(Issue.objects.filter(client=g.id), [
            3,
        ], lambda i: i.num)
        self.assertQuerysetEqual(Issue.objects.filter(cc__id__exact=g.id), [])
        self.assertQuerysetEqual(Issue.objects.filter(cc__id__exact=r.id), [
            2,
            3,
        ], lambda i: i.num)

        # These queries combine results from the m2m and the m2o relationships.
        # They're three ways of saying the same thing.
        self.assertQuerysetEqual(
            Issue.objects.filter(Q(cc__id__exact=r.id) | Q(client=r.id)), [
                1,
                2,
                3,
            ], lambda i: i.num)
        self.assertQuerysetEqual(
            Issue.objects.filter(cc__id__exact=r.id)
            | Issue.objects.filter(client=r.id), [
                1,
                2,
                3,
            ], lambda i: i.num)
        self.assertQuerysetEqual(
            Issue.objects.filter(Q(client=r.id) | Q(cc__id__exact=r.id)), [
                1,
                2,
                3,
            ], lambda i: i.num)
Exemplo n.º 12
0
 def test_foreign_key_exclusive(self):
     query = Query(ObjectC)
     where = query.build_where(Q(objecta=None) | Q(objectb=None))
     a_isnull = where.children[0]
     self.assertIsInstance(a_isnull, RelatedIsNull)
     self.assertIsInstance(a_isnull.lhs, SimpleCol)
     self.assertEqual(a_isnull.lhs.target,
                      ObjectC._meta.get_field('objecta'))
     b_isnull = where.children[1]
     self.assertIsInstance(b_isnull, RelatedIsNull)
     self.assertIsInstance(b_isnull.lhs, SimpleCol)
     self.assertEqual(b_isnull.lhs.target,
                      ObjectC._meta.get_field('objectb'))
Exemplo n.º 13
0
    def test_complex_query(self):
        query = Query(Author)
        where = query.build_where(Q(num__gt=2) | Q(num__lt=0))
        self.assertEqual(where.connector, OR)

        lookup = where.children[0]
        self.assertIsInstance(lookup, GreaterThan)
        self.assertEqual(lookup.rhs, 2)
        self.assertEqual(lookup.lhs.target, Author._meta.get_field('num'))

        lookup = where.children[1]
        self.assertIsInstance(lookup, LessThan)
        self.assertEqual(lookup.rhs, 0)
        self.assertEqual(lookup.lhs.target, Author._meta.get_field('num'))
Exemplo n.º 14
0
    def test_complex_filter(self):
        # The 'complex_filter' method supports framework features such as
        # 'limit_choices_to' which normally take a single dictionary of lookup
        # arguments but need to support arbitrary queries via Q objects too.
        self.assertQuerysetEqual(
            Article.objects.complex_filter({'pk': self.a1}),
            ['Hello'],
            attrgetter("headline"),
        )

        self.assertQuerysetEqual(
            Article.objects.complex_filter(Q(pk=self.a1) | Q(pk=self.a2)),
            ['Hello', 'Goodbye'],
            attrgetter("headline"),
        )
Exemplo n.º 15
0
 def test_select_for_update(self):
     self.assertSequenceEqual(
         Author.objects.annotate(
             book_jane=FilteredRelation('book', condition=Q(book__title__iexact='the book by jane a')),
         ).filter(book_jane__isnull=False).select_for_update(),
         [self.author2]
     )
Exemplo n.º 16
0
 def test_multiple_times(self):
     self.assertSequenceEqual(
         Author.objects.annotate(
             book_title_alice=FilteredRelation('book', condition=Q(book__title__icontains='alice')),
         ).filter(book_title_alice__isnull=False).filter(book_title_alice__isnull=False).distinct(),
         [self.author1]
     )
Exemplo n.º 17
0
 def test_combine_not_q_object(self):
     obj = object()
     q = Q(x=1)
     with self.assertRaisesMessage(TypeError, str(obj)):
         q | obj
     with self.assertRaisesMessage(TypeError, str(obj)):
         q & obj
Exemplo n.º 18
0
 def test_with_m2m(self):
     qs = Author.objects.annotate(
         favorite_books_written_by_jane=FilteredRelation(
             'favorite_books', condition=Q(favorite_books__in=[self.book2]),
         ),
     ).filter(favorite_books_written_by_jane__isnull=False)
     self.assertSequenceEqual(qs, [self.author1])
Exemplo n.º 19
0
 def test_exclude_relation_with_join(self):
     self.assertSequenceEqual(
         Author.objects.annotate(
             book_alice=FilteredRelation('book', condition=~Q(book__title__icontains='alice')),
         ).filter(book_alice__isnull=False).distinct(),
         [self.author2]
     )
Exemplo n.º 20
0
 def test_with_m2m_multijoin(self):
     qs = Author.objects.annotate(
         favorite_books_written_by_jane=FilteredRelation(
             'favorite_books', condition=Q(favorite_books__author=self.author2),
         )
     ).filter(favorite_books_written_by_jane__editor__name='b').distinct()
     self.assertSequenceEqual(qs, [self.author1])
Exemplo n.º 21
0
 def test_with_m2m_deep(self):
     qs = Author.objects.annotate(
         favorite_books_written_by_jane=FilteredRelation(
             'favorite_books', condition=Q(favorite_books__author=self.author2),
         ),
     ).filter(favorite_books_written_by_jane__title='The book by Jane B')
     self.assertSequenceEqual(qs, [self.author1])
Exemplo n.º 22
0
 def test_simple_query(self):
     query = Query(Author)
     where = query.build_where(Q(num__gt=2))
     lookup = where.children[0]
     self.assertIsInstance(lookup, GreaterThan)
     self.assertEqual(lookup.rhs, 2)
     self.assertEqual(lookup.lhs.target, Author._meta.get_field('num'))
Exemplo n.º 23
0
 def test_values_list(self):
     self.assertSequenceEqual(
         Author.objects.annotate(
             book_alice=FilteredRelation('book', condition=Q(book__title__iexact='poem by alice')),
         ).filter(book_alice__isnull=False).values_list('book_alice__title', flat=True),
         ['Poem by Alice']
     )
Exemplo n.º 24
0
 def test_without_join(self):
     self.assertSequenceEqual(
         Author.objects.annotate(
             book_alice=FilteredRelation('book', condition=Q(book__title__iexact='poem by alice')),
         ),
         [self.author1, self.author2]
     )
Exemplo n.º 25
0
 def test_values(self):
     self.assertSequenceEqual(
         Author.objects.annotate(
             book_alice=FilteredRelation('book', condition=Q(book__title__iexact='poem by alice')),
         ).filter(book_alice__isnull=False).values(),
         [{'id': self.author1.pk, 'name': 'Alice', 'content_type_id': None, 'object_id': None}]
     )
Exemplo n.º 26
0
 def test_extra(self):
     self.assertSequenceEqual(
         Author.objects.annotate(
             book_alice=FilteredRelation('book', condition=Q(book__title__iexact='poem by alice')),
         ).filter(book_alice__isnull=False).extra(where=['1 = 1']),
         [self.author1]
     )
Exemplo n.º 27
0
 def test_deconstruct_multiple_kwargs(self):
     q = Q(price__gt=F('discounted_price'), price=F('discounted_price'))
     path, args, kwargs = q.deconstruct()
     self.assertEqual(args, (
         ('price', F('discounted_price')),
         ('price__gt', F('discounted_price')),
     ))
     self.assertEqual(kwargs, {})
Exemplo n.º 28
0
 def test_internal_queryset_alias_mapping(self):
     queryset = Author.objects.annotate(
         book_alice=FilteredRelation('book', condition=Q(book__title__iexact='poem by alice')),
     ).filter(book_alice__isnull=False)
     self.assertIn(
         'INNER JOIN {} book_alice ON'.format(connection.ops.quote_name('filtered_relation_book')),
         str(queryset.query)
     )
Exemplo n.º 29
0
 def test_deconstruct_negated(self):
     q = ~Q(price__gt=F('discounted_price'))
     path, args, kwargs = q.deconstruct()
     self.assertEqual(args, ())
     self.assertEqual(kwargs, {
         'price__gt': F('discounted_price'),
         '_negated': True,
     })
Exemplo n.º 30
0
    def test_other_arg_queries(self):
        # Try some arg queries with operations other than filter.
        self.assertEqual(
            Article.objects.get(Q(headline__startswith='Hello'),
                                Q(headline__contains='bye')).headline,
            'Hello and goodbye')

        self.assertEqual(
            Article.objects.filter(
                Q(headline__startswith='Hello')
                | Q(headline__contains='bye')).count(), 3)

        self.assertSequenceEqual(
            Article.objects.filter(Q(headline__startswith='Hello'),
                                   Q(headline__contains='bye')).values(),
            [
                {
                    "headline": "Hello and goodbye",
                    "id": self.a3,
                    "pub_date": datetime(2005, 11, 29)
                },
            ],
        )

        self.assertEqual(
            Article.objects.filter(Q(headline__startswith='Hello')).in_bulk(
                [self.a1, self.a2]),
            {self.a1: Article.objects.get(pk=self.a1)})