Im trying to add a comment to my db, but getting error 'OrderedDict' object has no attribute 'pk'
The part of react.js
code handling the POST
request:
addComment() {
let url = this.props.post_url
axios.post('/api/comments/', {
post: url,
user: "http://127.0.0.1:8000/api/users/1/?format=json",
text: document.getElementsByName(url)[0].value,
csrfmiddlewaretoken: document.getElementsByName("csrfmiddlewaretoken")[0].value},
)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
My serializers.py:
from django.contrib.auth.models import User
from rest_framework import serializers
from .models import Post, Comment
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'url')
class CommentSerializer(serializers.HyperlinkedModelSerializer):
#user = UserSerializer(many=False, required=False)
class Meta:
model = Comment
fields = ('id', "post", "user", 'text')
read_only_fields = ('id', "user")
def create(self):
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
class PostSerializer(serializers.HyperlinkedModelSerializer):
#user = UserSerializer(required=False)
comments = CommentSerializer(many=True, required=False, read_only=True)
class Meta:
model = Post
fields = ('id', 'title', "user", "url", "comments", 'text')
read_only_fields = ('id', "url", "comments")
def save(self):
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
My views.py
from django.contrib.auth.models import User
from api.serializers import UserSerializer
from rest_framework import viewsets
from .models import Comment, Post
from .serializers import CommentSerializer, PostSerializer
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
class CommentViewSet(viewsets.ModelViewSet):
queryset = Comment.objects.all()
serializer_class = CommentSerializer
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
When sending the Post-request it goes througth normaly. If I remove one of the fields it returnes a 400
. Now Im getting this 500 [Internal server] error
.
AttributeError: 'OrderedDict' object has no attribute 'pk'
The error seems to be comming from:
/home/halvor1606/.virtualenvs/django-react/local/lib/python2.7/site-packages/rest_framework/relations.py in get_url
# Unsaved objects will not yet have a valid URL. if hasattr(obj, 'pk') and obj.pk in (None, ''): return None
Here-> lookup_value = getattr(obj, self.lookup_field) ...
kwargs = {self.lookup_url_kwarg: lookup_value} return self.reverse(view_name, kwargs=kwargs, request=request, format=format) def get_name(self, obj): return six.text_type(obj)
▶ Local vars are as follows:-
Variable Value
request <rest_framework.request.Request object at 0x7f4e59e75b90>
view_name 'post-detail'
obj OrderedDict([(u'title', u'adskjfj|'), (u'user', <User: halvor1606>), (u'text', u'kjkldsjf')])
self HyperlinkedIdentityField(read_only=True, view_name='post-detail')
format None
Read the other Questions with the same error. Didn't find one that solved my problem.
Thank you!
Edit:
Solved it by adding this to my post serializer:
def create(self, validated_data):
tmp_post = validated_data
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
post = Post.objects.create(
user=user,
title=tmp_post['title'],
text=tmp_post['text'],
)
return post
The ModelViewSet class inherits from GenericAPIView and includes implementations for various actions, by mixing in the behavior of the various mixin classes. The actions provided by the ModelViewSet class are . list() , . retrieve() , . create() , .
APIView allow us to define functions that match standard HTTP methods like GET, POST, PUT, PATCH, etc. Viewsets allow us to define functions that match to common API object actions like : LIST, CREATE, RETRIEVE, UPDATE, etc.
serializer_class - The serializer class that should be used for validating and deserializing input, and for serializing output. Typically, you must either set this attribute, or override the get_serializer_class() method.
Serializers in Django REST Framework are responsible for converting objects into data types understandable by javascript and front-end frameworks. Serializers also provide deserialization, allowing parsed data to be converted back into complex types, after first validating the incoming data.
I think this is simply because your url
here is empty:
addComment() {
let url = this.props.post_url
axios.post('/api/comments/', {
post: url,
user: "http://127.0.0.1:8000/api/users/1/?format=json",
text: document.getElementsByName(url)[0].value,
csrfmiddlewaretoken: document.getElementsByName("csrfmiddlewaretoken")[0].value},
)
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
}
Since you specified class CommentSerializer(serializers.HyperlinkedModelSerializer):
, this was mentioned in the document:
There needs to be a way of determining which views should be used for hyperlinking to model instances.
By default hyperlinks are expected to correspond to a view name that matches the style '{model_name}-detail', and looks up the instance by a pk keyword argument.
So the HyperlinkedModelSerializer
tries to find a view which should be used for the linking to Post object and could not find it. Highly suspected that the post url is with empty id
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With