Django API-фильтр поиска на других моделях без прямого иностранного поля - PullRequest
0 голосов
/ 12 апреля 2020

У меня есть две модели: пользователь, навык и профиль. Я пытаюсь реализовать фильтр поиска по навыкам пользователя. это означает, что когда кто-то ищет что-то, что содержится в навыках пользователя, этот пользователь появляется в результатах поиска.

Примечание. Когда пользователь регистрируется, для автоматического создания профиля используется сигнал. для этого пользователя. Пользователь просто обновляет свой профиль, чтобы добавить навыки и другие вещи.

модель пользователя

class User(AbstractBaseUser, PermissionsMixin):
    email = models.EmailField(max_length=254, unique=True)
    name = models.CharField(max_length=250)
    picture = models.TextField(null=True, blank=True)
    is_staff = models.BooleanField(default=False)
    is_superuser = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    last_login = models.DateTimeField(null=True, blank=True)
    date_joined = models.DateTimeField(auto_now_add=True)
    slug = models.SlugField(max_length=255, unique=True, blank=True)

модель профиля

class Profile(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profiles')
    date_of_birth = models.DateField(blank=True, verbose_name="DOB", null=True)
    bio = models.TextField(max_length=500, blank=True, null=True)
    skills = models.ManyToManyField(Skill, related_name='skills')
    sex = models.CharField(max_length=6, choices=SEX, blank=True, null=True)
    type_of_body = models.CharField(max_length=8, choices=BODYTYPE, blank=True, null=True)
    feet = models.PositiveIntegerField(blank=True, null=True)
    inches = models.PositiveIntegerField(blank=True, null=True)
    lives_in = models.CharField(max_length=50, blank=True, null=True)
    updated_on = models.DateTimeField(auto_now=True)

модель навыка

class Skill(models.Model):
    name = models.CharField(max_length=60)
    subcategory = models.CharField(max_length=60, blank=True, null=True)
    description = models.TextField(null=True, blank=True)
    created_on = models.DateTimeField(auto_now=True)
    updated_on = models.DateTimeField(auto_now_add=True)
    updated_by = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, on_delete=models.DO_NOTHING)

пользовательское представление, где поиск выполняется с

class ListUsersView(generics.ListAPIView):
    '''
    Gets all the users in the database
    '''
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [AllowAny]
    filter_backends = [filtr.SearchFilter]
    search_fields = ['email', 'name']

в настоящее время, решение выше работает, но когда я добавляю к search_fields другие поля, такие как profiles__skills, чтобы включить результаты там, где есть это умение, созданное пользователем, код не работает.

Пожалуйста, как я могу получить навыки в профиле пользователя для отображения в поиске?

1 Ответ

1 голос
/ 12 апреля 2020

Класс SearchFilter поддерживает простой поиск по одному параметру запроса. Атрибут search_fields должен представлять собой список имен полей текстового типа в модели.

profile__skills не является полем. Вы должны использовать текстовое поле, например. profile__skills__name

class ListUsersView(generics.ListAPIView):
    '''
    Gets all the users in the database
    '''
    queryset = User.objects.all()
    serializer_class = UserSerializer
    permission_classes = [AllowAny]
    filter_backends = [filtr.SearchFilter]
    search_fields = ['email', 'name', 'profiles__skills__name']
...