with tutorial latest framework español desde con cero applications python django django-q

python - latest - tutorial django



¿Cómo redactar dinámicamente un filtro de consulta OR en Django? (12)

En caso de que deseamos establecer programáticamente qué campo db queremos consultar:

import operator questions = [(''question__contains'', ''test''), (''question__gt'', 23 )] q_list = [Q(x) for x in questions] Poll.objects.filter(reduce(operator.or_, q_list))

De un ejemplo, puede ver un filtro O de consulta múltiple:

Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))

Por ejemplo, esto da como resultado:

[<Article: Hello>, <Article: Goodbye>, <Article: Hello and goodbye>]

Sin embargo, quiero crear este filtro de consulta de una lista. ¿Como hacer eso?

por ejemplo [1, 2, 3] -> Article.objects.filter(Q(pk=1) | Q(pk=2) | Q(pk=3))


Este es para la lista de pk dinámica:

pk_list = qs.values_list(''pk'', flat=True) # i.e [] or [1, 2, 3] if len(pk_list) == 0: Article.objects.none() else: q = None for pk in pk_list: if q is None: q = Q(pk=pk) else: q = q | Q(pk=pk) Article.objects.filter(q)


Otra opción que no conocía hasta hace poco: QuerySet también anula el & , | , ~ , etc, operadores. Las otras respuestas que los objetos OR Q son una mejor solución a esta pregunta, pero por el bien de interés / argumento, puede hacer:

id_list = [1, 2, 3] q = Article.objects.filter(pk=id_list[0]) for i in id_list[1:]: q |= Article.objects.filter(pk=i)

str(q.query) devolverá una consulta con todos los filtros en la cláusula WHERE .


Para crear consultas más complejas, también existe la opción de usar las constantes del objeto Q () Q.OR y Q.AND junto con el método add () como sigue:

list = [1, 2, 3] # it gets a bit more complicated if we want to dynamically build # OR queries with dynamic/unknown db field keys, let''s say with a list # of db fields that can change like the following # list_with_strings = [''dbfield1'', ''dbfield2'', ''dbfield3''] # init our q objects variable to use .add() on it q_objects = Q() # loop trough the list and create an OR condition for each item for item in list: q_objects.add(Q(pk=item), Q.OR) # for our list_with_strings we can do the following # q_objects.add(Q(**{item: 1}), Q.OR) queryset = Article.objects.filter(q_objects) # sometimes the following is helpful for debugging (returns the SQL statement) # print queryset.query


Puede encadenar sus consultas de la siguiente manera:

values = [1,2,3] # Turn list of values into list of Q objects queries = [Q(pk=value) for value in values] # Take one Q object from the list query = queries.pop() # Or the Q object with the ones remaining in the list for item in queries: query |= item # Query the model Article.objects.filter(query)


Puede usar el operador | = para actualizar programáticamente una consulta utilizando objetos Q.


Tal vez es mejor usar la instrucción SQL IN.

Article.objects.filter(id__in=[1, 2, 3])

Ver la referencia de queryset api .

Si realmente necesita realizar consultas con lógica dinámica, puede hacer algo como esto (feo + no probado):

query = Q(field=1) for cond in (2, 3): query = query | Q(field=cond) Article.objects.filter(query)


Una forma más corta de escribir la respuesta de Dave Webb usando la función de reducción de Python :

# For Python 3 only from functools import reduce values = [1,2,3] # Turn list of values into one big Q objects query = reduce(lambda q,value: q|Q(pk=value), values, Q()) # Query the model Article.objects.filter(query)


Usando la solución con reduce y or_ operador aquí, ¿cómo se puede filtrar por campos de multiplicación?

from functools import reduce from operator import or_ from django.db.models import Q filters = {''field1'': [1, 2], ''field2'': [''value'', ''other_value'']} qs = Article.objects.filter( reduce(or_, ( Q(**{f''{field}__in'': list_filters[field]}) for field in list_filters ) ) )

ps f es un nuevo formato cadenas literal aded en python3.6


Ver los docs :

>>> Blog.objects.in_bulk([1]) {1: <Blog: Beatles Blog>} >>> Blog.objects.in_bulk([1, 2]) {1: <Blog: Beatles Blog>, 2: <Blog: Cheddar Talk>} >>> Blog.objects.in_bulk([]) {}

Tenga en cuenta que este método solo funciona para búsquedas de claves primarias, pero parece ser lo que intenta hacer.

Entonces lo que quieres es:

Article.objects.in_bulk([1, 2, 3])


fácil..
desde django.db.models importa Q importa tu modelo args = (Q (visibility = 1) | (Q (visibility = 0) & Q (user = self.user))) #Tuple parameters = {} #dic order = ''create_at ''límite = 10

Models.objects.filter(*args,**parameters).order_by(order)[:limit]


from functools import reduce from operator import or_ from django.db.models import Q values = [1, 2, 3] query = reduce(or_, (Q(pk=x) for x in values))