Как фильтровать объекты по slug вместо id - PullRequest
0 голосов
/ 06 февраля 2019

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

В сериализаторе тегов я установил lookup_field в TagSerializer.Опция, когда я 'filter_field = (tags__name)' не подходит, потому что последнее GET изменение параметра предыдущее

class Event(models.Model):


tags = models.ManyToManyField('Tag')

...


class Meta:
    ordering = ['name']

def __str__(self):
    return self.name


class Tag(models.Model):
  name = models.CharField(unique=True, max_length=50)

  def __str__(self):
      return self.name

  def __unicode__(self):
      return '%s'% (self.name)



class EventSerializer(serializers.ModelSerializer):
  from accounts.api.serializers import ShortUserSerializer
  tags = serializers.SlugRelatedField(
      many=True,
      queryset=Tag.objects.all(),
      slug_field='name'
  )

  members_count = serializers.SerializerMethodField()

  author = ShortUserSerializer()

  max_members = serializers.IntegerField(required=False, default=-1)

  class Meta:
      model = Event
      fields = ['id', 'name', 'description', 'time_begins', 'author', 'members_count', 'max_members', 'tags',
              'avatar', 'date_expire', 'city', 'country', 'geo']
 ...

class TagSerializer(serializers.ModelSerializer):
  class Meta:
      model = Tag
      fields = '__all__'
      lookup_field = 'name'
      extra_kwargs = {
          'url': {'lookup_field': 'name'}
      }
...

class EventViewSet(viewsets.ModelViewSet):
  queryset = Event.objects.all()
  serializer_class = EventSerializer
  http_method_names = ['get', 'patch']
  filter_backends = (filters.SearchFilter, DjangoFilterBackend,)
  search_fields = ('name', 'author__username', )
  filter_fields = ('tags')

Я получаю результат с этим:

 `localhost:8000/events/?tags=1&tags=2`

И это на самом деле работает

Но мне нужно:

 `localhost:8000/events/?tags=#fun&tags=#movie`

1 Ответ

0 голосов
/ 06 февраля 2019

Этот случай не учитывается наборами фильтров по умолчанию, сгенерированными из filter_fields.Для внешних отношений используется идея.

Поэтому вы должны определить свой собственный набор фильтров следующим образом:

class EventFilter(filters.FilterSet):
    tags = filters.CharFilter(field_name="tags__name", method='filter_tags')

    class Meta:
        model = Event
        fields = ['tags']

    def filter_tags(self, queryset, name, tags):
        return queryset.filter(tags__name__contains=tags.split(','))

Затем вам нужно удалить filter_fields и добавить его в качестве * 1008.* в EventViewSet

class EventViewSet(viewsets.ModelViewSet):
  queryset = Event.objects.all()
  serializer_class = EventSerializer
  http_method_names = ['get', 'patch']
  filter_backends = (filters.SearchFilter, DjangoFilterBackend,)
  search_fields = ('name', 'author__username', )
  filter_class = EventFilter
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...