Django TemplateHTMLRenderer - Визуализация представления HTML - PullRequest
0 голосов
/ 05 июля 2018

Я пытаюсь отобразить некоторые объекты из моей модели в HTML. Сначала я думал, что это будет просто (и, вероятно, так и есть), но я сталкиваюсь с многочисленными ошибками.

В этом проекте я создал несколько представлений API, которые работают нормально (работают HintsListApiView и HintsRudView). Но в идеале я хотел бы использовать API для создания обычной HTML-страницы, доступной только для чтения, которую я затем могу стилизовать по своему желанию - мой HTMLAPIView. Я пытаюсь использовать TemplateHTMLRenderer, но сталкиваюсь с ошибками. Все, что я хочу, это чтобы атрибут text отображался в HTML. Фактические тексты - это всего лишь одно предложение. Это мои файлы:

models.py:

from django.db import models
from rest_framework.reverse import reverse as api_reverse

class Hints(models.Model):

    text = models.TextField(max_length=255)
    author = models.CharField(max_length=20)
    timestamp = models.DateTimeField(auto_now_add=True)


    def __str__(self):
        return str(self.text)

    def timestamp_pretty(self):
        return self.timestamp.strftime('%b %d %Y')

    def get_api_url(self, request=None):
        return api_reverse("api-hints1:hints-rud", kwargs={'pk': self.pk}, request=request)

views.py:

class HTMLAPIView(generics.RetrieveAPIView):
    lookup_field = 'pk'
    serializer_class = HTMLSerializer
    renderer_classes = (TemplateHTMLRenderer,)

    def get_queryset(self):
        queryset = Hints.objects.value('text')
        return Response({'queryset': queryset}, template_name='base.html') 



class HintsListApiView(mixins.CreateModelMixin, generics.ListAPIView):

    lookup_field = 'pk'
    serializer_class = HintsSerializer

    def get_queryset(self):
        qs = Hints.objects.all()
        query = self.request.GET.get("q")
        if query is not None:
            qs = qs.filter(
                Q(text__icontains=query)|
                Q(author__icontains=query)
                ).distinct()
        return qs

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)

    def get_serializer_context(self, *args, **kwargs):
        return {"request": self.request}



class HintsRudView(generics.RetrieveUpdateDestroyAPIView):

    lookup_field = 'pk'
    serializer_class = HintsSerializer

    def get_queryset(self):
        return Hints.objects.all()

    def get_serializer_context(self, *args, **kwargs):
        return {"request": self.request}

serializers.py:

class HintsSerializer(serializers.ModelSerializer):
    url = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = Hints
        fields = [
            'url',
            'id', 
            'text', 
            'author', 
            'timestamp_pretty'
            ]

        read_only_fields = ['timestamp_pretty', 'id']

    def get_url(self, obj):
        request = self.context.get("request")
        return obj.get_api_url(request=request)


class HTMLSerializer(serializers.ModelSerializer):

    class Meta:
        model = Hints
        fields = [ 
        'text', 
        ]

        read_only_fields = ['text',]

root urls.py:

from django.contrib import admin
from django.conf.urls import url, include
from rest_framework import routers, serializers, viewsets

urlpatterns = [
    url('admin/', admin.site.urls),
    url(r'^api/hints/', include(('hints1.api.urls', 'api'), namespace='api-hints1')),
    url(r'^api-auth/', include('rest_framework.urls')),
]

urls.py:

from .views import HintsRudView, HintsListApiView, HTMLAPIView
from . import views
from django.contrib import admin
from django.conf.urls import url, include
from rest_framework import routers, serializers, viewsets

urlpatterns = [
    url(r'^(?P<pk>\d+)$', HintsRudView.as_view(), name='hints-rud'),
    url(r'^$', HintsListApiView.as_view(), name='hints-list'),
    url(r'^html/', HTMLAPIView.as_view(), name='html' )    
]

Ошибки, с которыми я сталкивался, были разными, в настоящее время я сталкиваюсь с AttributeError в /api/hints/html/

Manager объект не имеет атрибута 'value'.

Я пробовал с и без сериализатора (потому что в документации упоминается, что TemplateHTMLRenderer не нужен). Я думаю, что проблема заключается в функции view.py и get_queryset. Я пробовал разные подходы, но получит другие ошибки, такие как

Контекст TypeError должен быть диктом, а не QuerySet.

Любая помощь, которая может быть оказана, будет принята с благодарностью! Спасибо!

1 Ответ

0 голосов
/ 11 июля 2018

Так что мне удалось сделать то, что я хотел. Но, честно говоря, я не совсем уверен, почему это сработало, поэтому, если кто-то может дать разъяснения, пожалуйста.

Я изменил свой HTMLAPIView в views.py на Viewset:

class HTMLAPIView(viewsets.ViewSet):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'base.html'
    serializer_class = HTMLSerializer


    def list(self, request):
        queryset = Hints.objects.order_by('pk')        
        return Response({'queryset': queryset}) 

Затем я получил ошибку в своем urls.py, но смог исправить это, включив часть словаря в .as_view()

url(r'^html/', HTMLAPIView.as_view({'get': 'list'}), name='html' )

Причина, по которой я не уверен, почему это сработало, заключается в том, что он возвращает мой text атрибут из моей модели так, как я хотел, но я не вижу, где я указал, что это правильный атрибут. Это только потому, что он первый?

Я также попытался закомментировать сериализатор, и он все еще работал нормально, поэтому я пришел к выводу, что причина не в этом.

...