переопределение имени группы ‘slug’ как группы 2; была группой 1 в позиции 50

#python-3.x #django-rest-framework

#python-3.x #django-rest-framework

Вопрос:

Я использую Django Rest-framework и создаю конечные точки для приложения, в котором есть несколько команд. У каждой «команды» есть несколько «Каналов». для простоты я разделяю свое приложение на два разных приложения.

  1. TeamsAPI
  2. ChannelsAPI

Я хочу отобразить каналы в виде гиперссылочного поля в списке команд.

 channels:[
    127.0.0.1:8000/api/teams/<team_slug>/channels/<channel_slug>/)
]
 

Сериализатор списка команд

 class TeamListSerializer(serializers.ModelSerializer):


     channels = serializers.HyperlinkedRelatedField(many=True,
                                               read_only=True,
                                               view_name='channel-detail',
                                               lookup_field='slug')
     .
     .
     .(other feilds)

class Meta:
    model = Team
    fields = (
        'channels',
         .
         .
         .(other fields)
    )
 

URL-адрес команд

 urlpatterns = [
  path('<slug:slug>/channels/', include('channelsapi.api.urls')),
  .
  .
  .(other urls)]
 

URL канала

  urlpatterns = [
  path('<slug:slug>/', ChannelDetailAPIView.as_view(), name='channel-detail'),
  .
  .
  .(other urls)]
 

Модель канала

 class Channel(models.Model):

    name = models.CharField(max_length=100)

    description = models.CharField(max_length=200, blank=True)

    team = models.ForeignKey(Team,
                         related_name='channels',
                         on_delete=models.CASCADE)

    slug = models.SlugField(unique=True)
    pinned = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
 

Сериализатор детализации канала

 class ChannelDetailSerializer(serializers.ModelSerializer):

    url = serializers.HyperlinkedIdentityField(read_only=True,
                                           view_name='channel-detail',
                                           lookup_field='slug')

    team = serializers.HyperlinkedRelatedField(read_only=True,
                                           view_name='team-detail',
                                           lookup_field='slug')

    class Meta:
        model = Channel
        fields = (
            'url',
            'slug',
            'name',
            'description',
            'team',
            'pinned',
            'created_at',
            'updated_at'
        )
        read_only_fields = ('created_at', 'updated_at')
        lookup_field = 'slug'
 

Ответ №1:

Я решил эту проблему, переопределив «HyperlinkedRelatedField». Вот код:

 class ChannelHyperlink(serializers.HyperlinkedRelatedField):
    view_name = 'channel-detail'
    queryset = Channel.objects.all()

    def get_url(self, obj, view_name, request, format):
        url_kwargs = {
            'slug': obj.team.slug,
            'pk': obj.pk
    }
        return reverse(view_name, kwargs=url_kwargs, request=request,     format=format)

    def get_object(self, view_name, view_args, view_kwargs):
        lookup_kwargs = {
            'team__slug': view_kwargs['slug'],
        'pk': view_kwargs['pk']
        }
        return self.get_queryset().get(**lookup_kwargs)
 

Теперь просто вызовите свой пользовательский сериализатор:

 channels = ChannelHyperlink(many=True)