django - framework - Filtro de negación de tastypie
django tastypie (5)
¿Hay un filtro de negación disponible por defecto. La idea es que puede hacer lo siguiente en el ORM de django:
model.objects.filter(field!=value)
¿Cómo puedo hacer eso en tastypie si eso es posible? Lo intenté:
someapi.com/resource/pk/?field__not=value
someapi.com/resource/pk/?field__!=value
someapi.com/resource/pk/?field!=value
Y todos me dieron errores.
He abierto un error para esto y proporcioné una solución simple aquí: https://github.com/toastdriven/django-tastypie/issues/524
Probablemente sería mejor agregar el ''!'' Carácter al final del nombre del campo como lo ha hecho en su pregunta ...
Lamentablemente no hay
El problema es que la clase ModelResource de Tastypie usa el método filter () del QuerySet solamente, es decir, no usa exclude () que debe usarse para filtros negativos. Sin embargo, no hay una búsqueda en el campo filtro () que signifique negación. Las búsquedas válidas son (después de esta publicación SO ):
exact
iexact
contains
icontains
in
gt
gte
lt
lte
startswith
istartswith
endswith
iendswith
range
year
month
day
week_day
isnull
search
regex
iregex
Sin embargo, no debería ser tan difícil implementar el soporte para algo como "__not_eq". Todo lo que necesita hacer es modificar el método apply_filters () y separar los filtros con "__not_eq" del resto. Luego debes pasar el primer grupo a exclude () y el resto a filter ().
Algo como:
def apply_filters(self, request, applicable_filters):
"""
An ORM-specific implementation of ``apply_filters``.
The default simply applies the ``applicable_filters`` as ``**kwargs``,
but should make it possible to do more advanced things.
"""
positive_filters = {}
negative_filters = {}
for lookup in applicable_filters.keys():
if lookup.endswith( ''__not_eq'' ):
negative_filters[ lookup ] = applicable_filters[ lookup ]
else:
positive_filters[ lookup ] = applicable_filters[ lookup ]
return self.get_object_list(request).filter(**positive_filters).exclude(**negative_filters)
en lugar de la predeterminada:
def apply_filters(self, request, applicable_filters):
"""
An ORM-specific implementation of ``apply_filters``.
The default simply applies the ``applicable_filters`` as ``**kwargs``,
but should make it possible to do more advanced things.
"""
return self.get_object_list(request).filter(**applicable_filters)
debe permitir la siguiente sintaxis:
someapi.com/resource/pk/?field__not_eq=value
No lo he probado. Probablemente también podría escribirse de una manera más elegante, pero debería ponerte en marcha :)
Nota sobre la respuesta anterior de Gorneau: parece que esto solo funciona si no estás usando un servidor MySQL. Ver:
# 1139 - Se obtuvo el error ''operando del operador de repetición no válido'' de regexp
Otra forma de hacer esto sin cambios en el código es usar un iregex con coincidencia inversa
http://HOST/api/v1/resource/?format=json&thing__iregex=^((?!notThis).)*$
Utilizo exclude () para evitar algunos valores. Por ejemplo:
Person.filter(name="Tim").exclude(state="Down");