Django REST framework: Как использовать несколько PK в URL с представлениями на основе классов / сериализатором - PullRequest
1 голос
/ 24 марта 2020

У меня есть две модели (примеры):

class Container(models.Model):
    name = models.CharField(max_length=100)

class ObjInContainer(models.Model):
    Container = models.ForeignKey(Container, on_delete=models.CASCADE)

A Container может иметь число N ObjInContainer.

Я пытаюсь написать REST API для выполнения две вещи:

Первое: увидеть все ObjInContainer из одного Container:

# urls.py
url(r'^container/(?P<container_id>\d+)/objects_in_container/$', ContainerObjectsListAPIView.as_view(), name='container_objects_list'),

# views.py
class ContainerObjectsListAPIView(ListAPIView):
    queryset = ObjInContainer.objects.all()
    queryset = queryset.prefetch_related('container')
    serializer_class = ContainerObjectsListAPIView

# serializer.py
class ContainerObjectsListAPIView(ModelSerializer):
    container = SerializerMethodField()
    class Meta:
        model = ObjInContainer
        fields = [
            'id',
            'container',
        ]
    def get_container(self, obj):
        return str(obj.container.name)

Но в этом списке перечислены все ObjInContainer из ALL Container. Как мне сообщить REST Framework, что Container, необходимый для получения ObjInContainer, - это тот, который в URL-адресе от <container_id>?

Полагаю, в views.py, где я объявляю queryset = ObjInContainer.objects.all(), действительно должно быть queryset = ObjInContainer.objects.filter(container_id=container_id), но как мне получить доступ к части <container_id> URL-адреса в классе представления?

Любой мой второй вопрос - как детализировать один ObjInContainer, используя два разных идентификатора в URL?

# urls.py
url(r'^container/(?P<container_id>\d+)/objects_in_container/(?P<obj_in_container_id>\d+)/$', ContainerObjDetailAPIView.as_view(), name='container_object_detail'),

# views.py
class ContainerObjDetailAPIView(RetrieveAPIView):
    queryset = ObjInContainer.objects.all()
    serializer_class = ContainerObjDetailSerializer

# serializer.py
class ContainerObjDetailSerializer(ModelSerializer):
    container = SerializerMethodField()
    class Meta:
        model = ObjInContainer
        fields = [
            'id',
            'container',
        ]
    def get_container(self, obj):
        return str(obj.container.name)

Итак, если я go на URL container/2/objects_in_container/55/, как мне сообщить REST Framework, что первый идентификатор (container_id=2) предназначен для экземпляра Container, и второй идентификатор (obj_in_container_id=55) предназначен для экземпляра ObjInContainer?

Я полагаю, что обе проблемы действительно сводятся к тому, как Django определяет RegEx из URL и где именно они отфильтровываются и применяется к моделям в БД?

1 Ответ

0 голосов
/ 25 марта 2020

Ответ на первый вопрос: Если вы хотите показать список ObjInContainer, когда они нажимают на соответствующий URL-адрес Container, вы можете использовать идентификатор Container в URL-адресе для фильтрации. the ObjInContainer view`:

class ContainerObjectsListAPIView(ListAPIView):
serializer_class = ContainerObjectsSerializer #I assume you have a typo in your code

def get_queryset(self):
    id= self.kwargs['id']
    return ObjInContainer.objects.filter(container__id=id)

Ответ на второй вопрос: Зачем вам два идентификатора, чтобы получить один объект? Достаточно только идентификатора ObjInContainer.

...