In django rest framework If i use DictField() in serializer its given me AttributeError at /api/v1/analytics/reports-configuration/1/
‘str’ object has no attribute ‘items’ error.please take a look.
serializers.py
import json
from rest_framework import serializers
from models import ReportConfiguration
class ReportConfigurationSerializer(serializers.ModelSerializer):
report_type = serializers.ChoiceField(choices=['query', 'activity', 'summary'])
read_only = serializers.BooleanField(required=True)
query_data = serializers.DictField(required=True)
class Meta:
model = ReportConfiguration
fields = ('id', 'title', 'query_data', 'created_by', 'last_activity_by', 'deleted',
'deleted_by', 'added_at', 'last_activity_at', 'report_type', 'read_only')
def validate(self, data):
if data['report_type'] is not 'summary' and data['read_only'] is True:
raise serializers.ValidationError("If read only true then report type should be summary")
if data['report_type'] is 'summary' and data['read_only'] is not True:
raise serializers.ValidationError("If read only not true then report type should not be summary")
return data
def create(self, validated_data):
validated_data['created_by'] = self.context['request'].user
validated_data['last_activity_by'] = self.context['request'].user
return ReportConfiguration.objects.create(**validated_data)
views.py
class ReportConfigurationViewSet(viewsets.ModelViewSet):
serializer_class = ReportConfigurationSerializer
queryset = ReportConfiguration.objects.all()
permission_classes = (permissions.IsAuthenticated,)
filter_backends = (DjangoFilterBackend,)
filter_class = ReportFilter
def list(self, request):
response = super(ReportConfigurationViewSet, self).list(request)
for data in response.data['results']:
data['query_data'] = json.loads(data['query_data'])
return response
def retrieve(self, request, pk=None):
response = super(ReportConfigurationViewSet, self).retrieve(request, pk=pk)
response.data['query_data'] = json.loads(response.data['query_data'])
return response
models.py
class ReportConfiguration(models.Model):
class ReportTypeChoice(Choice):
QueryReport = 'query'
ActivityReport = 'activity'
SummaryList = 'summary'
title = models.CharField(max_length=300, unique=True, blank=False, null=False)
query_data = JSONField(default={})
created_by = models.ForeignKey(User, null=True, blank=True, related_name='report_created_by')
last_activity_by = models.ForeignKey(User, null=True, blank=True,related_name='last_active_in_report')
deleted = models.BooleanField(default=False)
deleted_by = models.ForeignKey(User, null=True, blank=True, related_name='report_deleted_by')
added_at = models.DateTimeField(auto_now_add=True)
last_activity_at = models.DateTimeField(default=timezone.now)
report_type = models.CharField(max_length=15, choices=ReportTypeChoice)
read_only = models.BooleanField(default=False)
Error:
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
ERROR Internal Server Error: /api/v1/analytics/reports-configuration/1/
Traceback (most recent call last):
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/django/core/handlers/base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/django/core/handlers/base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/viewsets.py", line 83, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/views.py", line 477, in dispatch
response = self.handle_exception(exc)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/views.py", line 437, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/views.py", line 474, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/ranvijay.s/wk/project/django/dhanalytics/views.py", line 47, in retrieve
response = super(ReportConfigurationViewSet, self).retrieve(request, pk=pk)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/mixins.py", line 58, in retrieve
return Response(serializer.data)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/serializers.py", line 527, in data
ret = super(Serializer, self).data
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/serializers.py", line 262, in data
self._data = self.to_representation(self.instance)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/serializers.py", line 496, in to_representation
ret[field.field_name] = field.to_representation(attribute)
File "/Users/ranvijay.s/.virtualenvs/my_project/lib/python2.7/site-packages/rest_framework/fields.py", line 1601, in to_representation
for key, val in value.items()
AttributeError: 'str' object has no attribute 'items'
Related
I'm trying to use multiupload in django form for upload several images at once.
I'm using django ModelForm but when i'm calling form.is_valid() in function-base view or using generic.FormView, i'm getting 'list' object has no attribute 'name' error. in generic.FormView neither of form_valid and form_invalid methods aren't called. although when I use request.POST.get(some_data) it works without any errors but I want to use generic.FormView for some validations. I think the validation of the form makes the error happen.
so what should I do?
here is my code.
models.py
class Post(models.Model):
post_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False, unique=True)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE, related_name="posts")
text = models.TextField(max_length=1000)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
...
class Image(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name="images")
image = models.ImageField(upload_to="images/posts/")
forms.py
class PostForm(forms.ModelForm):
images = MultiImageField(min_num=1, max_num=3)
class Meta:
model = models.Post
fields = ("text", "images")
views.py
class CreatePostView(LoginRequiredMixin, generic.FormView):
template_name = "posts/post_create.html"
form_class = forms.PostForm
def get_success_url(self):
return redirect("profile", slug=self.request.kwargs.slug)
def form_valid(self, form):
...
# some codes
...
return super(CreatePostView, self).form_valid(form)
error:
Traceback (most recent call last):
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\generic\base.py", line 84, in view
return self.dispatch(request, *args, **kwargs)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\contrib\auth\mixins.py", line 73, in dispatch
return super().dispatch(request, *args, **kwargs)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\generic\base.py", line 119, in dispatch
return handler(request, *args, **kwargs)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\views\generic\edit.py", line 152, in post
if form.is_valid():
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\forms.py", line 205, in is_valid
return self.is_bound and not self.errors
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\forms.py", line 200, in errors
self.full_clean()
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\forms.py", line 433, in full_clean
self._clean_fields()
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\forms.py", line 443, in _clean_fields
value = field.clean(value, bf.initial)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\fields.py", line 670, in clean
return super().clean(data)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\fields.py", line 200, in clean
self.run_validators(value)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\forms\fields.py", line 185, in run_validators
v(value)
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\validators.py", line 611, in validate_image_file_extension
return FileExtensionValidator(allowed_extensions=get_available_image_extensions())(
File "C:\Users\asus\AppData\Local\Programs\Python\Python310\lib\site-packages\django\core\validators.py", line 576, in __call__
extension = Path(value.name).suffix[1:].lower()
Exception Type: AttributeError at /profile/ehsanadmin/post/create/
Exception Value: 'list' object has no attribute 'name'
I try to POST request but I got KeyError.
Exception Location: C:\github\dj-postgres-heroku\get_staff\serializers.py, line 32, in create
Here is error location and that line is this.
def create(self, validated_data):
**profile_data = validated_data.pop('profile')**
I try to POST data like this.
enter image description here
enter image description here
{
"profile":1,
"title": "일단 10만원, 업무 마친 후 바로 입금",
"hourly_pay": 12500,
"start_date": "2020-05-06",
"end_date": "2020-05-09",
"start_time": "09:00:00",
"end_time": "18:00:00",
"content": "간단업무입니다.",
"jobs":[1, 2]
}
Here are my code all.
models.py
class GetStaffPost(models.Model):
profile = models.ForeignKey(Profile, null=True, on_delete=models.CASCADE) # default=1 -> pk=1
title = models.CharField(max_length=30)
jobs = models.ManyToManyField(Job, blank=True) # tag랑 비슷
hourly_pay = models.IntegerField(null=True)
start_date = models.DateField(null=True)
end_date = models.DateField(null=True)
start_time = models.TimeField(null=True)
end_time = models.TimeField(null=True)
created_at = models.DateTimeField(null=True, auto_now_add=True)
content = models.TextField(default='content')
class Meta:
ordering = ['-created_at']
def __str__(self):
return f'{self.pk}: {self.title} - {self.profile.nickname}'
serializers.py
class GetStaffPostSerializer(serializers.ModelSerializer):
profile = serializers.PrimaryKeyRelatedField(read_only=True)
jobs = serializers.PrimaryKeyRelatedField(read_only=True, many=True)
class Meta:
model = GetStaffPost
# fields = ['id', 'profile', 'title', 'jobs', 'hourly_pay', 'start_date', 'end_date',
# 'start_time', 'end_time', 'created_at', 'content']
fields = "__all__"
def create(self, validated_data): # profile, jobs
profile_data = validated_data.pop('profile')
profile_id = profile_data
profile = Profile.objects.get(pk=profile_id)
jobs_data = validated_data.pop('jobs') # list?
post = GetStaffPost.objects.create(**validated_data,
profile=profile) # Direct assignment to the forward side of a many-to-many set is prohibited. Use jobs.set() instead.
for job_data in jobs_data:
post.jobs.add(Job.objects.get(pk=job_data))
return profile
views.py
class GetStaffPostViewSet(viewsets.ModelViewSet):
queryset = GetStaffPost.objects.all()
serializer_class = GetStaffPostSerializer
def perform_create(self, serializer):
serializer.save()
when POST request , I want to write only profile pk and jobs pk list. not all fields in model Profile and Jobs.
And when GET request, I want to show all fields.
This is Traceback.
[17/Nov/2021 12:31:43] "GET /get_staff/post/ HTTP/1.1" 200 16613
Internal Server Error: /get_staff/post/
Traceback (most recent call last):a
File "C:\github\dj-postgres-heroku\venv\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
response = get_response(request)
File "C:\github\dj-postgres-heroku\venv\lib\site-packages\django\core\handlers\base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\github\dj-postgres-heroku\venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "C:\github\dj-postgres-heroku\venv\lib\site-packages\rest_framework\viewsets.py", line 125, in view
return self.dispatch(request, *args, **kwargs)
File "C:\github\dj-postgres-heroku\venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
File "C:\github\dj-postgres-heroku\venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\github\dj-postgres-heroku\venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\github\dj-postgres-heroku\venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
File "C:\github\dj-postgres-heroku\venv\lib\site-packages\rest_framework\mixins.py", line 19, in create
self.perform_create(serializer)
File "C:\github\dj-postgres-heroku\get_staff\views.py", line 21, in perform_create
serializer.save()
File "C:\github\dj-postgres-heroku\venv\lib\site-packages\rest_framework\serializers.py", line 205, in save
self.instance = self.create(validated_data)
File "C:\github\dj-postgres-heroku\get_staff\serializers.py", line 32, in create
profile_data = validated_data.pop('profile')
KeyError: 'profile'
As you add profile field read_only=True thats why validated_data doesn't have profile key.
Provode profile primary key in request body and remove read_only=True from profile field.
I am trying to list and paginate favourite post of users. I got a custom pagination snippet from so, which I am using here, But I am getting this error.
ValueError:Cannot use QuerySet for "Post": Use a QuerySet for "Account".
I guess, there are problems with my serializer or views. can anyone please help me fix this issue?
These are the codes:
serializers:
class PostSerializer(serializers.ModelSerializer):
user = serializers.ReadOnlyField(source='user.username')
post_date = serializers.ReadOnlyField()
comment_set = CommentSerializer(many=True)
class Meta:
model = Post
fields = ['id','title', 'post_date', 'user', 'image', 'comment_set']
class PostFavouriteListSerializer(serializers.ModelSerializer):
favourite = PostSerializer(many=True, read_only=True)
class Meta:
model = Post
fields = ['favourite',]
views
class CustomPaginator(PageNumberPagination):
page_size = 3
def generate_response(self, query_set, serializer_obj, request):
try:
page_data = self.paginate_queryset(query_set, request)
except NotFoundError:
return Response({"error": "No results found for the requested page"}, status=status.HTTP_400_BAD_REQUEST)
serialized_page = serializer_obj(page_data, many=True)
return self.get_paginated_response(serialized_page.data)
class FavouritePostAPIView(APIView):
authentication_classes = (TokenAuthentication,)
permission_classes = (IsAuthenticated,)
def get(self, request):
user = self.request.user
favourite_posts = Post.objects.filter(favourite=user.post_favourite.all())
paginator = CustomPaginator()
response = paginator.generate_response(post, PostFavouriteListSerializer, request)
return response
This is the Post model:
class Post(models.Model):
title = models.TextField(max_length=5000, blank=False, null=False)
image = models.ImageField(upload_to='posts/postimage/', null=True)
post_date = models.DateTimeField(auto_now_add=True, verbose_name="Date Posted")
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
slug = models.SlugField(blank=True, unique=True, max_length=255)
favourite = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='post_favourite', blank=True)
Traceback:
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\views\decorators\csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\views\generic\base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\rest_framework\views.py" in dispatch
505. response = self.handle_exception(exc)
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\rest_framework\views.py" in handle_exception
465. self.raise_uncaught_exception(exc)
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\rest_framework\views.py" in raise_uncaught_exception
476. raise exc
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\rest_framework\views.py" in dispatch
502. response = handler(request, *args, **kwargs)
File "C:\danny\Project\posts\api\views.py" in get
186. favourite_posts = Post.objects.filter(favourite=user.post_favourite.all())
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\manager.py" in manager_method
82. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\query.py" in filter
892. return self._filter_or_exclude(False, *args, **kwargs)
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\query.py" in _filter_or_exclude
910. clone.query.add_q(Q(*args, **kwargs))
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\sql\query.py" in add_q
1290. clause, _ = self._add_q(q_object, self.used_aliases)
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\sql\query.py" in _add_q
1315. child_clause, needed_inner = self.build_filter(
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\sql\query.py" in build_filter
1224. self.check_related_objects(join_info.final_field, value, join_info.opts)
File "C:\Users\danny\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\db\models\sql\query.py" in check_related_objects
1079. raise ValueError(
Exception Type: ValueError at /api/posts/posts/favourites/
Exception Value: Cannot use QuerySet for "Post": Use a QuerySet for "Account".
replace :
favourite_posts = Post.objects.filter(favourite=user.post_favourite.all())
paginator = CustomPaginator()
response = paginator.generate_response(post, PostFavouriteListSerializer, request)
by :
favourite_posts = user.post_favourite.all()
paginator = CustomPaginator()
response = paginator.generate_response(favourite_posts, PostSerializer, request)
the related m2m post_favourite is a queryset of post , not need to filter/get this, so you dont need PostFavouriteListSerializer
alternative can be this:
favourite_posts = Post.objects.filter(favourite=user)
you get all post with favourite have your user
I am using Django Rest Framework. I have an existing database (cannot make any changes to it). I have composite pk on my table TestSuite. When I do a get() on the test_suites it throws an error - 'str' object has no attribute 'pk' . I haven't defined pk in my model, as with django I cannot define composite primary keys. Hence, django uses 'id' an autogenerated pk for the model. I cannot add id in my database (as I cannot modify the db).
The post() works as expected, however get() is throwing error through postman() as well as browsable API.
I am new to DRF. Any help is appreciated.
DB create statement:
CREATE TABLE `test_suite` (
`team_name` varchar(30) NOT NULL,
`suite_name` varchar(100) NOT NULL,
`description` varchar(200) DEFAULT NULL,
`schedule` varchar(100) DEFAULT NULL,
`email_list_ok` varchar(200) DEFAULT NULL,
`email_list_fail` varchar(200) DEFAULT NULL,
`template_name` varchar(100) NOT NULL,
PRIMARY KEY (`team_name`,`suite_name`),
KEY `fk_test_suite__email_templates` (`template_name`),
CONSTRAINT `fk_test_suite__email_templates` FOREIGN KEY (`template_name`) REFERENCES `email_templates` (`template_name`),
CONSTRAINT `fk_test_suite__team` FOREIGN KEY (`team_name`) REFERENCES `team` (`team_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I need to do a get() and post() to this table. Below are my models , serializers and viewsets.
models.py
class Team(models.Model):
team_name = models.CharField(primary_key=True, max_length=30)
description = models.CharField(max_length=100, blank=True, null=True)
class Meta:
managed = False
db_table = 'team'
class TestSuite(models.Model):
team_name = models.ForeignKey(Team, on_delete=models.DO_NOTHING, db_column='team_name')
suite_name = models.CharField(max_length=100)
description = models.CharField(max_length=200, blank=True, null=True)
schedule = models.CharField(max_length=100, blank=True, null=True)
email_list_ok = models.CharField(max_length=200, blank=True, null=True)
email_list_fail = models.CharField(max_length=200, blank=True, null=True)
template_name = models.ForeignKey(EmailTemplates, on_delete=models.DO_NOTHING, db_column='template_name')
class Meta:
managed = False
db_table = 'test_suite'
unique_together = (('team_name', 'suite_name'),)
views.py
class TestSuiteViewSet(viewsets.ModelViewSet):
queryset = models.TestSuite.objects.values('team_name','suite_name', 'description','schedule','email_list_ok','email_list_fail','template_name')
serializer_class = serializers.TestSuiteSerializer
class TeamViewSet(viewsets.ModelViewSet):
queryset = models.Team.objects.all()
serializer_class = serializers.TeamSerializer
serializers.py
class TestSuiteSerializer(serializers.ModelSerializer):
class Meta:
model = models.TestSuite
fields = ['team_name','suite_name', 'description','schedule','email_list_ok','email_list_fail','template_name']
Error Traceback:
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.6/contextlib.py" in inner
52. return func(*args, **kwds)
File "/usr/local/lib/python3.6/dist-packages/django/views/decorators/csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/viewsets.py" in view
116. return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in dispatch
495. response = self.handle_exception(exc)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in handle_exception
455. self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in dispatch
492. response = handler(request, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/mixins.py" in list
48. return Response(serializer.data)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in data
768. ret = super(ListSerializer, self).data
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in data
262. self._data = self.to_representation(self.instance)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in to_representation
686. self.child.to_representation(item) for item in iterable
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in <listcomp>
686. self.child.to_representation(item) for item in iterable
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in to_representation
530. ret[field.field_name] = field.to_representation(attribute)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/relations.py" in to_representation
272. return value.pk
Exception Type: AttributeError at /dqf_api/test_suites/
Exception Value: 'str' object has no attribute 'pk'
urls.py
router = routers.DefaultRouter()
router.register(r'teams', views.TeamViewSet)
router.register(r'test_suites', views.TestSuiteViewSet)
urlpatterns = [ url(r'^dqf_api/', include(router.urls))]
EDIT:
I was able to resolve get()by adding below code to my serializers.py However, now my post() is not working - ValueError at /dqf_api/test_suites/
Cannot assign "'ede'": "TestSuiteModel.team_name" must be a "Team" instance.
def to_representation(self, obj):
return {
'team_name': obj.get('team_name'),
'suite_name': obj.get('suite_name'),
'description': obj.get('description'),
'schedule': obj.get('schedule'),
'email_list_ok': obj.get('email_list_ok'),
'email_list_fail': obj.get('email_list_fail'),
'template_name': obj.get('template_name'),
}
def to_internal_value(self, data):
return {
'team_name': data.get('team_name'),
'suite_name': data.get('suite_name'),
'description': data.get('description'),
'schedule': data.get('schedule'),
'email_list_ok': data.get('email_list_ok'),
'email_list_fail': data.get('email_list_fail'),
'template_name': data.get('template_name'),
}
Error Traceback:
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/exception.py" in inner
35. response = get_response(request)
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py" in _get_response
128. response = self.process_exception_by_middleware(e, request)
File "/usr/local/lib/python3.6/dist-packages/django/core/handlers/base.py" in _get_response
126. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/usr/lib/python3.6/contextlib.py" in inner
52. return func(*args, **kwds)
File "/usr/local/lib/python3.6/dist-packages/django/views/decorators/csrf.py" in wrapped_view
54. return view_func(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/viewsets.py" in view
116. return self.dispatch(request, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in dispatch
495. response = self.handle_exception(exc)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in handle_exception
455. self.raise_uncaught_exception(exc)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/views.py" in dispatch
492. response = handler(request, *args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/mixins.py" in create
21. self.perform_create(serializer)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/mixins.py" in perform_create
26. serializer.save()
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in save
214. self.instance = self.create(validated_data)
File "/usr/local/lib/python3.6/dist-packages/rest_framework/serializers.py" in create
943. instance = ModelClass._default_manager.create(**validated_data)
File "/usr/local/lib/python3.6/dist-packages/django/db/models/manager.py" in manager_method
82. return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/usr/local/lib/python3.6/dist-packages/django/db/models/query.py" in create
415. obj = self.model(**kwargs)
File "/usr/local/lib/python3.6/dist-packages/django/db/models/base.py" in __init__
477. _setattr(self, field.name, rel_obj)
File "/usr/local/lib/python3.6/dist-packages/django/db/models/fields/related_descriptors.py" in __set__
197. self.field.remote_field.model._meta.object_name,
Exception Type: ValueError at /dqf_api/test_suites/
Exception Value: Cannot assign "'ede'": "TestSuiteModel.team_name" must be a "Team" instance.
There was issue with serialization and deserialization with foreign key relations. I fixed it by adding below code to the serializers.py
class TestSuiteSerializer(serializers.ModelSerializer):
class Meta:
model = models.TestSuiteModel
fields = ['team_name','suite_name', 'description','schedule','email_list_ok','email_list_fail','template_name']
def to_representation(self, obj):
if isinstance(obj, dict): # get methods
return obj
else:
self.fields['team_name'] = TeamSerializer()
self.fields['template_name'] = EmailTemplatesSerializer()
return super(TestSuiteSerializer, self).to_representation(obj)
I've read a bunch of similar sounding questions of SO, but somehow none of them have helped me solve my particular case. I added a ManyToManyField to represent "Likes" to my Photo model:
class Photo(TimestampModerated):
owner = models.ForeignKey('auth.User', related_name='photos', on_delete=models.CASCADE)
uuid = models.UUIDField(default=uuid4, editable=False)
slug = models.SlugField(max_length=80, editable=False)
title = models.CharField(max_length=80, blank=False, null=False)
description = models.TextField(verbose_name='description of entity', blank=True, null=True)
photo = models.ImageField(upload_to=user_directory_path, height_field="height", width_field="width", blank=True)
height = models.IntegerField(blank=True)
width = models.IntegerField(blank=True)
tags = TaggableManager(blank=True)
hash = models.CharField(max_length=64, unique=True, null=True)
size = models.BigIntegerField('size of file in bytes', blank=True, null=True)
likes = models.ManyToManyField('auth.User', blank=True, null=True)
class Meta:
verbose_name_plural = "photos"
def __str__(self):
return self.title
def delete(self, using=None, keep_parents=False):
default_storage.delete("{}".format(self.photo))
super().delete()
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Photo, self).save(*args, **kwargs)
Here is the view (at least the part that should matter for creating):
class PhotoViewSet(viewsets.ModelViewSet):
queryset = Photo.objects.all()
serializer_class = PhotoSerializer
authentication_classes = (TokenAuthentication,)
permission_classes = (IsOwnerOrReadOnly, permissions.AllowAny,)
parser_classes = (MultiPartParser, FormParser)
def perform_create(self, serializer):
serializer.save(owner=self.request.user, likes=[])
And here is the serializer:
class PhotoSerializer(serializers.ModelSerializer, TaggitSerializer):
owner = serializers.CharField(source='owner.username', read_only=True)
tags = TagListSerializerField()
photo = Base64ImageField(
max_length=None, use_url=True,
)
class Meta:
model = Photo
fields = ('photo', 'height', 'width', 'owner', 'slug', 'uuid', 'title', 'id', 'created', 'updated',
'moderation_code', 'tags', 'hash', 'description', 'size', 'likes')
def create(self, validated_data):
photo = Photo.objects.create(owner=validated_data.pop('owner'),
**validated_data)
p = Photo.objects.get(uuid=photo.uuid)
[p.tags.add(tag) for tag in validated_data['tags']]
return photo
To be clear, the only thing that has been added is the likes field in the model. Also, I should note that I am able to actually POST new likes to photos that already existed in the DB before the migration. I'm just having issues creating new instances. Any ideas?
Here is the full error traceback:
Internal Server Error: /api/photos/
Traceback (most recent call last):
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 58, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/viewsets.py", line 86, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/views.py", line 489, in dispatch
response = self.handle_exception(exc)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/views.py", line 449, in handle_exception
self.raise_uncaught_exception(exc)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/views.py", line 486, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/mixins.py", line 21, in create
self.perform_create(serializer)
File "/Users/xxxxxx/_/photos/views.py", line 24, in perform_create
serializer.save(owner=self.request.user, likes=[])
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/rest_framework/serializers.py", line 215, in save
self.instance = self.create(validated_data)
File "/Users/xxxxxx/_/photos/serializers.py", line 88, in create
**validated_data)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/query.py", line 392, in create
obj = self.model(**kwargs)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/base.py", line 566, in __init__
_setattr(self, prop, kwargs[prop])
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 536, in __set__
manager = self.__get__(instance)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 513, in __get__
return self.related_manager_cls(instance)
File "/Users/xxxxxx/_/.virtualenv/lib/python3.6/site-packages/django/db/models/fields/related_descriptors.py", line 830, in __init__
(instance, self.pk_field_names[self.source_field_name]))
ValueError: "<Photo: photo-260561.jpeg>" needs to have a value for field "id" before this many-to-many relationship can be used.
Well, I solved this with one seemingly very simple line of code:
def create(self, validated_data):
validated_data.pop('likes') ## adding this line solved the issue
photo = Photo.objects.create(owner=validated_data.pop('owner'),
**validated_data)
p = Photo.objects.get(uuid=photo.uuid)
[p.tags.add(tag) for tag in validated_data['tags']]
return photo
If anyone can explain why this works, I'd be interested to know. I should point out that for this use case a photo would never be initiated with likes.