Pedro Costa
Pedro Costa

Reputation: 437

DJANGO - 'str' object has no attribute 'data'

I am doing a project using Django and DRF. I have a view which lists the details of an item (Conta). And all the fields are editable so the user can edit the object. The problem is a get the error: 'str' object has no attribute 'data'

The code:

class ContaDetailsHTML(APIView):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'conta_details.html'

    def get(self, request, pk):
        user = request.user
        conta = get_object_or_404(Conta, pk=pk,user=user)
        serializer = ContaDetailsSerializerHTML(conta)
        return Response({'serializer': serializer, 'conta': conta})

    def post(self, request, pk):
        user = request.user
        conta = get_object_or_404(Conta, pk=pk, user=user)
        serializer = ContaDetailsSerializerPosts(conta, data=request.data)
        if not serializer.is_valid():
            return Response({'serializer': serializer, 'conta': conta})
        serializer.save()
        return Response(status=status.HTTP_200_OK)

And in the templates:

{% load rest_framework %}

<html><body>

<h1>Conta - {{ conta.nome }}</h1>

<form action="{% url 'conta_details' pk=2 %}" method="POST">
    {% csrf_token %}
    {% render_form serializer %}
    <input type="submit" value="Save">
</form>

</body></html>

the pk=2 is just for testing purposes.

When i edit the fields and press Save, that error pops up. Any ideas?

EDIT, URL:

url(r'^api/contas/(?P<pk>[0-9]+)/$', views.ContaDetailsHTML.as_view(), name='conta_details'),

EDIT, Error Traceback

Environment:


Request Method: POST
Request URL: http://localhost:8000/project/api/contas/2/

Django Version: 1.10.5
Python Version: 3.6.0
Installed Applications:
['project.apps.ProjectConfig',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error:
In template C:\Documentos\Mestrado\ISCN\django\PF\project\templates\conta_details.html, error at line 9
   'str' object has no attribute 'data'   1 : {% load rest_framework %}
   2 : 
   3 : <html><body>
   4 : 
   5 : <h1>Conta - {{ conta.nome }}</h1>
   6 : 
   7 : <form action="{% url 'conta_details' pk=2 %}" method="POST">
   8 :     {% csrf_token %}
   9 :      {% render_form serializer %} 
   10 :     <input type="submit" value="Save">
   11 : </form>
   12 : 
   13 : </body></html>

Traceback:

File "C:\Python36-32\lib\site-packages\django\core\handlers\exception.py" in inner
  39.             response = get_response(request)

File "C:\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  217.                 response = self.process_exception_by_middleware(e, request)

File "C:\Python36-32\lib\site-packages\django\core\handlers\base.py" in _get_response
  215.                 response = response.render()

File "C:\Python36-32\lib\site-packages\django\template\response.py" in render
  109.             self.content = self.rendered_content

File "C:\Python36-32\lib\site-packages\rest_framework\response.py" in rendered_content
  72.         ret = renderer.render(self.data, accepted_media_type, context)

File "C:\Python36-32\lib\site-packages\rest_framework\renderers.py" in render
  174.         return template_render(template, context, request=request)

File "C:\Python36-32\lib\site-packages\rest_framework\compat.py" in template_render
  306.         return template.render(context, request=request)

File "C:\Python36-32\lib\site-packages\django\template\backends\django.py" in render
  66.             return self.template.render(context)

File "C:\Python36-32\lib\site-packages\django\template\base.py" in render
  208.                     return self._render(context)

File "C:\Python36-32\lib\site-packages\django\template\base.py" in _render
  199.         return self.nodelist.render(context)

File "C:\Python36-32\lib\site-packages\django\template\base.py" in render
  994.                 bit = node.render_annotated(context)

File "C:\Python36-32\lib\site-packages\django\template\base.py" in render_annotated
  961.             return self.render(context)

File "C:\Python36-32\lib\site-packages\django\template\library.py" in render
  203.         output = self.func(*resolved_args, **resolved_kwargs)

File "C:\Python36-32\lib\site-packages\rest_framework\templatetags\rest_framework.py" in render_form
  31.     return renderer.render(serializer.data, None, {'style': style})

Exception Type: AttributeError at /project/api/contas/2/
Exception Value: 'str' object has no attribute 'data'

Upvotes: 0

Views: 6244

Answers (1)

Nabeel Ahmed
Nabeel Ahmed

Reputation: 19282

The files seem to be fine, except the line:

serializer = ContaDetailsSerializerPosts(conta, data=request.data)

Probably, where the issue can be i.e.

conta = get_object_or_404(Conta, pk=pk, user=user)
serializer = ContaDetailsSerializerPosts(conta, data=request.data)

What if you're getting 404 (Not Found) in conta (as you're trying to post/create an entry with id=2, how can you query it first), and when you pass on to Serializer data structure/type other the QuerySet, this is the error you might get:

'str' object has no attribute 'data'

Probable Solution: Get rid of the line

conta = get_object_or_404(Conta, pk=pk, user=user)

make the serilaizer call as

serializer = ContaDetailsSerializerPosts(data=request.data)

If you're using the same view for create (POST) and update (PUT) make it:

if pk: # the update request 
    conta = get_object_or_404(Conta, pk=pk, user=user)
    serializer = ContaDetailsSerializerPosts(conta, data=request.data)
else:  # the create request
    serializer = ContaDetailsSerializerPosts(data=request.data)

Upvotes: 1

Related Questions