update serializers modelserializer framework errors create python django django-rest-framework query-optimization

python - serializers - serializer create django



Disminuir el nĂºmero de bloques elif (3)

Estoy tratando de hacer un filtro basado en los siguientes queryparams .

¿Cómo puedo disminuir las líneas de código?

if fridge == ''true'' and toilet == ''true'' and side_window == ''true'': queryset = queryset.filter(toilet=True, fridge=True, sun_side_window=True) elif fridge == ''true'' and toilet == ''true'': queryset = queryset.filter(toilet=True, fridge=True) elif fridge == ''true'' and side_window == ''true'': queryset = queryset.filter(sun_side_window=side_window.capitalize(), fridge=fridge.capitalize()) elif toilet == ''true'' and side_window == ''true'': queryset = queryset.filter(sun_side_window=side_window.capitalize(), toilet=toilet.capitalize()) elif fridge == ''true'': queryset = queryset.filter(fridge=fridge.capitalize()) elif toilet == ''true'': queryset = queryset.filter(toilet=toilet.capitalize()) elif side_window == ''true'': queryset = queryset.filter(sun_side_window=True)


¿Qué tal crear una función como

def q(**kwargs): for k in kwargs: if kwargs[k] == ''true'': kwargs[k] = True return queryset.filter(**kwargs)

Solo necesita asignar sun_side_window a side_window alguna manera, o eliminarlo.


Supongo que por ''true''.capitalize() , te refieres al valor booleano True , y no a la cadena ''True''

Primero, convierta ''true'' en True . Luego, construya un diccionario que contenga los argumentos de la palabra clave que se pasarán a queryset.filter . Estoy haciendo estos dos pasos en un único diccionario de comprensión:

vars = {''fridge'': fridge, ''toilet'': toilet, ''side_window'': side_window} kwargs = {kw: True for kw in vars if vars[kw] == ''true''}

Si no está familiarizado con las comprensiones, esto es equivalente a:

kwargs = {} for kw in vars: if vars[kw] == ''true'': kwargs[vars] = True

A continuación, descomprime este diccionario y queryset.filter a queryset.filter :

queryset = queryset.filter(**kwargs)

Desempaquetar el diccionario equivale a pasar sus pares clave / valor como argumentos clave a la función.

f(a=1, b=2) # is equivalent to kw = {''a'': 1, ''b'': 2} f(**kw)

Como nota al margen, no sé de queryset , pero parece un módulo. Si es así, no recomendaría reasignar el resultado de queryset.filter a queryset ...


k = {} if fridge == "true": k["fridge"] = True if toilet == "true": k["toilet"] = True if side_window == "true": k["sun_side_window"] = True q = queryset.filter(**k)