Поиск в нескольких моделях

#django #django-models #django-rest-framework

#django #django-модели #django-rest-framework

Вопрос:

У меня есть два класса моделей следующим образом, которые связаны друг с другом с User помощью class.

 class Person(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    ...
    first_name = models.CharField(max_length=30, null=False, blank=False)
    last_name = models.CharField(max_length=30, null=False, blank=False)
    father_name = models.CharField(max_length=30, null=False, blank=False) 


class Company(models.Model): 
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    ...
    code = models.CharField(max_length=15, null=True, blank=True)
 

И теперь a request выглядит следующим образом:

 http://localhost:8000/api/v1/search/users/?first_name=johnamp;amp;last_name=devamp;amp;code=25
 

Как я могу выполнить поиск, если один из входных параметров находится в одной из таблиц (person или company)?

Усилия, которые я приложил, но результата не найдено:

 class SearchUserAPI(APIView):
    def get(self, request, format=None):
        try:
            from django.db.models import Q

            q = request.query_params

            search_models = [Person, Company]
            search_results = []
            for model in search_models:
                fields = [x for x in model._meta.fields if isinstance(x, django.db.models.CharField)]
                search_queries = [Q({x.name   "__icontains": q.get(x.name)}) for x in fields]
                print(search_queries)
                q_object = Q()
                for query in search_queries:
                    q_object = q_object | query
                results = model.objects.filter(q_object)
                search_results.append(results)
                
            data = [search_results]

            return Response(data, status=status.HTTP_200_OK)

        except Exception as e:
            return Response({"error": e}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
 

Комментарии:

1. может SearchFilter быть?

2. В вашем ответе на запрос должны быть только модели person? Или модели компании тоже?

3. Почему бы вам не попробовать?

4. @ТаалайДюшебеков Следует выполнить поиск в каждой таблице, и если в одной из таблиц найден один из входных параметров, должен быть возвращен идентификатор пользователя (родительская таблица).

Ответ №1:

это будет лучше и будет работать, я надеюсь)

 class SearchUserAPI(APIView):
    def get(self, request, format=None):
        try:
            q = request.query_params
            first_name = q.get('first_name')
            last_name = q.get('last_name')
            code = q.get('code')
            data = Person.objects.filter(first_name=first_name, last_name=last_name, company_code=code)
            data = [search_results]

            return Response(data, status=status.HTTP_200_OK)

        except Exception as e:
            return Response({"error": e}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
 

также вы можете легко добавить другие поля для фильтрации

Ответ №2:

вы можете использовать filterset в drf Я предполагаю, что ваш пользователь каким-то образом связан с человеком или компанией во внешнем ключе или один к одному

 from django_filters import rest_framework as filters, BaseInFilter

class SearchFilter(filters.FilterSet):
    first_name = filters.CharFilter(
        field_name="person__first_name",
        label='person name'
    )
    last_name = filters.CharFilter(
            field_name="person__first_name",
            label='person name'
        )
    code = = filters.NumberFilter(
            field_name="company__code",
            label='code'
        )
    


class Meta:
    model = User
    fields = ['first_name','last_name','code']
 

Вы можете просто вызвать свой searchfilter, установленный в views, теперь он будет выполнять вашу работу