Как добавить имя пользователя в filterset_fields в views Django Rest Framework, где пользователь является внешним ключом модели?

#django #django-rest-framework #django-filter

#django #django-rest-framework #django-filter

Вопрос:

У меня есть модель ниже models.py , в которой User в качестве внешнего ключа используется модель django, и я хочу добавить username filterset_fields ее в my views , чтобы фильтровать занятость пользователя по username идентификатору пользователя вместо. Любая помощь была бы отличной! Спасибо!

 class UserEmployment(models.Model):

    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='employment')
    position = models.TextField(blank=True)
    company = models.TextField(blank=True)
    start_year = models.IntegerField(blank=True, null=True)
    end_year = models.IntegerField(blank=True, null=True)
    currently_work = models.BooleanField(default=False)
 

Класс сериализатора,

 class UserEmploymentSerializer(serializers.ModelSerializer):

    class Meta:
        model = UserEmployment
        fields = ['id', 'user', 'position', 'company', 'start_year', 'end_year', 'currently_work']
 

Класс просмотра,

 class UserEmploymentViewSet(viewsets.ModelViewSet):

    queryset = UserEmployment.objects.all()
    serializer_class = UserEmploymentSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = ['user'] # I want this to be 'username' in order to filter employment list by username
    http_method_names = ['get']
 

Спасибо!

Ответ №1:

Вы можете использовать filterset_class attr .

 from django_filters import rest_framework
class UserEmploymentFilter(rest_framework.FilterSet):
    username = rest_framework.CharFilter(field_name='user__username', lookup_expr='iexact')

    class Meta:
        fields = ("username",)
        model = UserEmployment
    
 

И ваше представление должно быть таким

 class UserEmploymentViewSet(viewsets.ModelViewSet):

    queryset = UserEmployment.objects.all()
    serializer_class = UserEmploymentSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_class = UserEmploymentFilter
    http_method_names = ['get']
 

После этого вы можете выполнить поиск с помощью ?username=foo

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

1. Большое вам спасибо. Это сработало! Я также попробовал переопределить метод get_queryset(), и он также работает нормально. Какой способ лучше, как вы думаете?

2. На мой взгляд, filterset-class лучше, чем переопределить queryset, поскольку ваше представление не увеличится

3. Да! Еще раз большое спасибо!

Ответ №2:

Это также отлично работает,

 class UserEmploymentViewSet(viewsets.ModelViewSet):

    queryset = UserEmployment.objects.all()
    serializer_class = UserEmploymentSerializer
    filter_backends = [DjangoFilterBackend]
    http_method_names = ['get']

    def get_queryset(self):
    
        queryset = UserEmployment.objects.all()
        username = self.request.query_params.get('username', None)
        if username is not None:
            queryset = queryset.filter(user__username=username)
        return queryset
 

Ссылка: https://www.django-rest-framework.org/api-guide/filtering/#filtering-against-query-parameters