#python-3.x #django-rest-framework
#python-3.x #django-rest-framework
Вопрос:
Я использую Django Rest-framework и создаю конечные точки для приложения, в котором есть несколько команд. У каждой «команды» есть несколько «Каналов». для простоты я разделяю свое приложение на два разных приложения.
- TeamsAPI
- 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)