0

Hello dear stack overflowers, I've set up a Django project with restful framework and I use JSON response in order to retrieve data from the server in a structured manner.

models.py

class Container(models.Model):     
    created = models.DateTimeField(auto_now_add=True)     
    title = models.CharField(max_length=100, blank=False, default='content')     
    content = models.TextField()      

        class Meta:         
            ordering = ['created']

The problematic code:

views.py

class ContentView(RetrieveAPIView):
    queryset = Container.objects.all()
    serializer_class = ContainerSerializer
    def get_object(self):
        queryset = self.get_queryset()
        serializer = ContainerSerializer(queryset,many=True)
        return JsonResponse(serializer.data , safe=False)

Gives the following error when being executed:

AttributeError: Got AttributeError when attempting to get a value for field `title` on serializer `ContainerSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `JsonResponse` instance.
Original exception text was: 'JsonResponse' object has no attribute 'title'.
[21/May/2021 17:27:13] "GET /content/ HTTP/1.1" 500 18789

To be as clear as possible I'll attach the serializer's code:

serializers.py

class ContainerSerializer(serializers.Serializer):
    id = serializers.IntegerField(read_only=True)
    title = serializers.CharField(required=True, allow_blank=False, max_length=100)
    content = serializers.CharField()

    def create(self, validated_data):
        return Container.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.title = validated_data.get('title', instance.title)
        instance.content = validated_data.get('content', instance.content)
        instance.save()
        return instance

Before switching to RetrieveAPIView, everything worked well with the test server. The error arised while switching to this new-for-me method of making requests.

Any help will be appreciated!

Daniel
  • 3,228
  • 1
  • 7
  • 23
Mike K.
  • 15
  • 1
  • 6
  • Any reason you didn't use a `ModelSerializer` and `ModelViewSet` ? – Daniel May 21 '21 at 18:48
  • @Daniel Thanks for pointing that out, I've tried ```ModelSerializer``` but now the JSON output looks weird, in a way I haven't seen before. it looks nested. I guess it has something to do with multiple encapsulations of the content – Mike K. May 21 '21 at 19:56
  • Can you share your models ? – Daniel May 21 '21 at 19:57
  • @Daniel ```class Container(models.Model): created = models.DateTimeField(auto_now_add=True) title = models.CharField(max_length=100, blank=False, default='content') content = models.TextField() class Meta: ordering = ['created']``` I'll update the question for it to look readable... – Mike K. May 21 '21 at 19:59

1 Answers1

1

Let's try model serializers like so: Remeber, you need to update the serializers.py, views.py, and urls.py file to get this to work:

serialiers.py

from rest_framework import serializers
from . import models

class ContainerSerializer(serializers.ModelSerializer):

    class Meta:
        model = models.Container
        fields = ['id', 'created', 'title', 'content']

views.py

from rest_framework import viewsets
from . import serializers
from . import models

class ContainerViewSet(viewsets.ModelViewSet):

    serializer_class = serializers.ContainerSerializer
    queryset = models.Container.objects.order_by('id')

urls.py

from django.urls import include, path
from rest_framework import routers
from . import views

# rest:
router = routers.DefaultRouter()
router.register('containers', views.ContainerViewSet)

urlpatterns = [
    ...
    path('api/', include(router.urls))
]

Now we have full access to rest, so we can do get, put, post, patch, and delete requests, etc. A getrequest to the url <base-url>/api/containers should return something like:

[
  {
    'id' : 1,
    'created' : 'YYYY-MM-DD',
    'title' : 'title-1',
    'content' : 'content-1'
  },
  {
    'id' : 2,
    'created' : 'YYYY-MM-DD',
    'title' : 'title-2',
    'content' : 'content-2'
  }
]
Daniel
  • 3,228
  • 1
  • 7
  • 23
  • 1
    No problem - the advantage with model serializers is that most of the logic is already written - instead you'll spend your time configuring details like what fields are accessible, writable, nested, etc. – Daniel May 21 '21 at 20:26