Платформа Django Rest отличается форматом ответа для того же URL и HTTP-метода

#python #django #django-rest-framework

#python #django #django-rest-framework

Вопрос:

Я работаю над приложением, в котором используется Django Rest Framework для обработки запросов, и я использую плагин django-rest-framework-datatables, который помогает мне обрабатывать разбивку на страницы в таблицах данных.

Работает нормально, но когда я запрашиваю единый регистр, он продолжает выдавать мне формат json для таблиц данных, например:

 {
    "count": 1,
    "next": null,
    "previous": null,
    "results": [{
        "id": 1,
        "name": "University of Passo Fundo",
        "country": "Brazil"
    }]
}
  

Это не большая проблема, но я бы предпочел получать только поле результата. Как я могу определить два разных формата ответа для одного и того же URL и одного и того же метода, просто проверяя параметры запроса в django rest framework?

Следуйте моему коду:

urls.py

 router = routers.DefaultRouter()
router.register(r'institution', InstitutionViewSet, base_name='Institution')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api-auth/', include('rest_framework.urls')),

    # api
    path('api/', include(router.urls)),

    # views
    url(r'^$', Home.as_view(), name='index'),
    url(r'institution/', Institution.as_view(), name='institution'),
]
  

serializer.py

 class InstitutionSerializer(serializers.ModelSerializer):

    class Meta:
        model = Institution
        fields = '__all__'
        datatables_always_serialize = ('id', 'name', 'country')
  

models.py

 class Institution(models.Model):
    id = models.AutoField(db_column='id', primary_key=True)
    name = models.CharField(db_column='name', max_length=255, null=False)
    country = models.CharField(db_column='country', max_length=255, null=False)

    class Meta:
        db_table = 'Institution'
        managed = True
        verbose_name = 'Institutions'
        verbose_name_plural = 'Institutions'
        ordering = ['id']

    def __str__(self):
        return self.name
  

views.py

 class InstitutionViewSet(viewsets.ModelViewSet):
    serializer_class = InstitutionSerializer
    def get_queryset(self):
        if 'type' in self.request.GET and self.request.GET['type'] == 'edit':
            return Institution.objects.filter(id=self.request.GET['id'])
        return Institution.objects.all().order_by('id')
  

Ответ №1:

Прежде всего, именно так Django отображает ответ для разбивки на страницы. Таким образом, вы можете увидеть следующий или предыдущий список элементов на основе страницы.

И, во-вторых, вы должны переопределить представление списка в Django, чтобы оно было таким:

 class InstituttionViewSet(viewsets.ModelViewSet):
    serializer_class = InstitutionSerializer
    pagination_class = None

    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
  

Здесь мы переопределяем метод list, который отвечает за отображение списка элементов API. Таким образом, сначала он получит все элементы в queryset , затем передаст их сериализатору, чтобы записать их в определенный формат, и, наконец, вернет список в json для ответа.

Кроме того, помните, что я также установил pagination_class=None , чтобы Django больше не использовал разбивку на страницы для API.

Ответ №2:

Я думаю, вам не следует переопределять метод get_queryset view, это должно решить вашу проблему. Представления drf обрабатывают параметр по умолчанию по умолчанию с помощью retrieve метода. Вы можете использовать свой собственный класс разбиения на страницы для редактирования схемы ответа.

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

1. метод извлечения не отвечает за возврат списка элементов. Он должен переопределить list метод ModelViewSet.

2. Он написал об одном элементе, я думаю — «Я запрашиваю единый регистр, он продолжает предоставлять мне формат json для таблиц данных»

3. Как он упомянул, datatables предназначены для отображения списка элементов. И извлечение должно получить элемент pk из URL в путь к views.py

Ответ №3:

Вы можете переопределить метод, get_serializer_class и использовать два разных сериализатора, зависящих от параметра запроса.