es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo agregar búsquedas Q con get_queryset en Django rest framework?

He escrito código de filtrado en la función get_queryset. También tengo una API de filtrado por búsqueda separada que busca en función de la cadena proporcionada en el parámetro de consulta de búsqueda. Ahora lo que quiero es agregar la consulta de búsqueda en la lógica de filtrado anterior para que el usuario pueda buscar solo en los resultados filtrados y no desde toda la base de datos nuevamente.

Mi modelo:

class Producto (modelos.Modelo):

GARANTÍA = (
    ('no_warranty', 'Sin Garantía',),
    ('local_seller_warranty', 'Garantía del vendedor local',),
    ('brand_warranty', 'Garantía de marca',),
)

comerciante = modelos.ForeignKey (Vendedor, en_eliminar=modelos.CASCADE, en_blanco=True, nulo=True)
categoría = modelos.ManyToManyField (Categoría, en_blanco=False)
sub_categoría = modelos.ForeignKey (Subcategoría, en_eliminar=modelos.CASCADE, en_blanco=True, nulo=True)
mini_categoria = modelos.ForeignKey (Minicategoría, en_eliminar=modelos.SET_NULL, en_blanco=True, nulo=True)
marca = modelos.ForeignKey (Marca, en_eliminar=modelos.CASCADE)
colección = modelos.ForeignKey (Colección, en_eliminar=modelos.CASCADE)
destacado = modelos.BooleanField (predeterminado=False)  # ¿Es el producto destacado?

/.........otros códigos.........../

Mi vista de filtrado:

class ProductoAPIView (ListAPIView):
clases_de_permisos = [AllowAny]
serializador_clase = ProductoSerializador
queryset = Producto.objetos.todos()
clase de paginación = PaginaciónPersonalizada

def get_queryset (self):
    marca = self.request.GET.get ('brand', None)
    sub_categoría = self.request.GET.get ("sub_category", None)
    garantía = self.request.GET.get ("garantía", None)
    if marca no es None:

        brand_values ​​= marca.split (",")
        if sub_categoría no es None:

            sub_category_values ​​= sub_categoría.split (",")
            if garantía no es None:

                warranty_values ​​= warranty.split (",")
                return Producto.objetos.filter (marca__nombre__en = valores de marca,
                                              sub_categoría__nombre__en = sub_category_values,
                                              garantía__en = valores de garantía)

      /..........otros códigos........../

Mi URL para llamar a esto

localhost/api/productos?brand=Samsung,Lg&warranty=no_warranty

Vista de búsqueda de consulta Q:

from django.db.models import Q
class PrdouctSearchAPIView (ListAPIView):
clases_de_permisos = [AllowAny]
queryset = Producto.objetos.todos()
serializador_clase = ProductoSerializador
clase de paginación = PaginaciónPersonalizada

def get_queryset (self):
    qur = self.request.query_params.get ('search')
    item = Producto.objetos.filter (Q (categoría__nombre__icontains = qur) |
                                      Q (marca__nombre__icontains = qur) |
                                      Q (descripción__icontains = qur) |
                                      Q (colección__nombre__icontains = qur) |
                                      Q (nombre__icontains = qur) |
                                      Q (variantes__color__icontains = qur)). distintivo()

    return item

URL para realizar esta vista:

localhost/api/productsearch?search=frontload

Ahora lo que quiero es combinar las dos API como localhost/api/productos?brand=Samsung Necesito mostrar solo máquinas de la marca Samsung. Ahora, cuando agrego search = frontload en la misma API localhost/api/products?brand=Samsung&search=frontload como Necesito mostrar máquinas Samsung con cargar frontal solamente. ¿Cómo hacerlo?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para combinar las dos APIs, se puede modificar la función get_queryset de ProductAPIView para incluir el parámetro de búsqueda en la lógica de filtrado. Aquí hay un ejemplo:

    from django.db.models import Q
    
    class ProductAPIView(ListAPIView):
        permission_classes = [AllowAny]
        serializer_class = ProductSerializer
        queryset = Product.objects.all()
        pagination_class = CustomPagination
    
        def get_queryset(self):
            brand = self.request.GET.get('brand', None)
            sub_category = self.request.GET.get("sub_category", None)
            warranty = self.request.GET.get("warranty", None)
            search_query = self.request.query_params.get('search', None)
    
            qs = Product.objects.all()
            if brand:
                brand_values = brand.split(",")
                qs = qs.filter(brand__name__in=brand_values)
            if sub_category:
                sub_category_values = sub_category.split(",")
                qs = qs.filter(sub_category__name__in=sub_category_values)
            if warranty:
                warranty_values = warranty.split(",")
                qs = qs.filter(warranty__in=warranty_values)
            if search_query:
                qs = qs.filter(Q(category__name__icontains=search_query) |
                               Q(brand__name__icontains=search_query) |
                               Q(description__icontains=search_query) |
                               Q(collection__name__icontains=search_query) |
                               Q(name__icontains=search_query) |
                               Q(variants__color__icontains=search_query)).distinct()
    
            return qs
    

    En esta función modificada, primero se obtienen los valores de todos los parámetros de filtro de los parámetros de consulta (marca, subcategoría, garantía). Luego, se obtiene el valor del parámetro search. Finalmente, se crea una consulta qs mediante Product.objects.all().

    Luego, se aplican los filtros a esta consulta uno por uno según los valores de los parámetros de filtro. Después de eso, se comprueba si search_query no es None. Si no es None, se aplica el filtro de búsqueda a la consulta mediante el objeto Q, que permite realizar consultas complejas utilizando operadores OR.

    Por último, se devuelve la consulta filtrada.

    Ahora, puede llamar a la API con parámetros de filtro y consultas de búsqueda de la siguiente manera:

    localhost/api/products?brand=Samsung&search=frontload
    

    Esto devolverá solo las máquinas Samsung que tienen la consulta de búsqueda “frontload” en su nombre, descripción o color de variante.

Comments are closed.