QuerySet object has no attribute 'user' on Django Rest Framework - python

I cannot serialize a model to get results while performing requests on Django Rest Framework.
models.py
class Karfarma(models.Model):
user = models.OneToOneField(User, related_name='karfarma', on_delete=models.CASCADE)
mobile = models.TextField(max_length=11)
validation_number = models.TextField(max_length=5, blank=True, default=None)
phone_number = models.TextField(max_length=10, blank=True, default=None)
datetime_join_persian = models.DateTimeField(default=None, null=True)
def __unicode__(self):
return "%s %s" % (self.user.first_name, self.user.last_name)
serializers.py
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
views.py
class UserList(APIView):
queryset = User.objects.all()
def get(self, request):
users = User.objects.all()
serializer = UserSerializer(users)
return Response(serializer.data)
Here's the reduced version of the error which I get when I perform the request:
AttributeError: Got AttributeError when attempting to get a value for field user on serializer UserSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the QuerySet instance.
Original exception text was: 'QuerySet' object has no attribute 'user'.

Whenever you are trying to pass a queryset to a serializer always pass it with UserSerializer(users,many=True). If you just want to pass a single user object you can use User.objects.get(some_attribue=something) and then pass that object to the serializer without the many=True flag.

finally I found what was wrong
view was the problem when ever you want to get list of objects you should pass argument many=True to the serializer.
the problem was this

Related

Django rest framework serializer Got AttributeError when attempting to get a value for field `field` on serializer. Try to nest serializers

AttributeError: Got AttributeError when attempting to get a value for field vesting_choice_id on serializer VestingLocationRateSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the QuerySet instance.
Original exception text was: 'QuerySet' object has no attribute 'vesting_choice_id'.
Model
class VestingChoice(models.Model):
id = UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
participant = ForeignKey('Participant', on_delete=CASCADE, related_name="participants_id")
vesting = ForeignKey('Vesting', on_delete=CASCADE, related_name="vestings")
class VestingLocationRate(models.Model):
id = UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
vesting_choice_id = ForeignKey('VestingChoice', on_delete=CASCADE,
related_name="vesting_choice")
country_id = ForeignKey(Country, on_delete=CASCADE, related_name="country_id")
Serializers
class VestingChoiceSerializer(serializers.ModelSerializer):
class Meta:
model = VestingChoice
fields = "__all__"
class VestingLocationRateSerializer(serializers.ModelSerializer):
vesting_choice_id = VestingChoiceSerializer(many = False)
country_id = CountrySerializer(many = False)
class Meta:
model = VestingLocationRate
fields = "__all__"
In vesting_choice_id on_delete=models.CASCADE not on_delete=CASCADE
And seems like you haven't migrate after adding vesting_choice_id,
so try to run python manage.py makemigrations then python manage.py migrate
If you're trying to fetch multiple instances of your model, make sure that in your view function, at the serialization level, you have set many to True
Something like this
models = YourModel.objects.all()
serializer = YourModelSerializer(models, many=True)
return JsonResponse(serializer.data, safe=False)

AssertionError when calling put or create in Django Rest Framework

I am trying to update my Teachers view in DRF by instead of including the link to the department field, I would display the name of the department. When I added the PrimaryKeyRelated field, I was able to see the department.name but couldnt use update or create within DRF. Is there a way I could change the display without causing the need for the methods or is that not the case?
Error
The `.update()` method does not support writable dotted-source fields by default.
Write an explicit `.update()` method for serializer `school.serializers.TeacherSerializer`, or set `read_only=True` on dotted-source serializer fields.
The `.create()` method does not support writable dotted-source fields by default.
Write an explicit `.create()` method for serializer `school.serializers.TeacherSerializer`, or set `read_only=True` on dotted-source serializer fields.
models.py
class Department(models.Model):
name = models.CharField(max_length=300)
def __str__(self):
return self.name
class Teacher(models.Model):
name = models.CharField(max_length=300)
department = models.ForeignKey(Department, on_delete=models.CASCADE)
tenure = models.BooleanField()
def __str__(self):
return f'{self.name} teaches {self.department}'
# dont need success url if get_absolute_url on create and update view
def get_absolute_url(self):
return reverse('teacher', kwargs={'pk': self.pk})
serializers.py
class TeacherSerializer(serializers.HyperlinkedModelSerializer):
department = serializers.PrimaryKeyRelatedField(
source='department.name', queryset=Department.objects.all())
class Meta:
model = Teacher
fields = ['url', 'name', 'department', 'tenure']
class DepartmentSerializer(serializers.HyperlinkedModelSerializer):
teacher_set = TeacherSerializer(many=True, required=False)
class Meta:
model = Department
fields = ['url', 'name', 'teacher_set']
views.py
class TeacherViewSet(viewsets.ModelViewSet):
queryset = Teacher.objects.all()
serializer_class = TeacherSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
class DepartmentViewSet(viewsets.ModelViewSet):
queryset = Department.objects.all()
serializer_class = DepartmentSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
have you tried add related_name for model Teacher in field foreign key and call in serializers? link to docs

Django rest framework AttributeError after GET request

During a GET request, Django give me this error:
Got AttributeError when attempting to get a value for field `name` on serializer `projectSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `ProjectTask` instance.
Original exception text was: 'ProjectTask' object has no attribute 'name'.
I'm pretty new to django and rest_framework, here's the code:
models.py
class Project(models.Model):
name = models.CharField(max_length=50)
class ProjectTask(models.Model):
project = models.ForeignKey(Project,on_delete=models.CASCADE)
description = models.CharField(max_length=200)
status = models.IntegerField()
serializers.py
class projectTaskSerializer(serializers.ModelSerializer):
class Meta:
model = ProjectTask
fields = ['description','status']
class projectSerializer(serializers.ModelSerializer):
tasks = projectTaskSerializer(many=True)
class Meta:
model = Project
fields = ['name','tasks']
views.py (I'm only mentioning the get function that is being called to avoid cluttering the question
def get(self, request):
projects = ProjectTask.objects.all()
serialized_projects = projectSerializer(projects,many = True)
return Response({'projects' : serialized_projects.data})

How to serialize Inherited models in Django REST Framework

I'm working on a Django Rest Framework project, in which I have created the following models as:
from django.db import models
# Base Models...
choices = (
('Single', 'Single'),
('Multiple', 'Multiple'),
)
class UserAccountModel(models.Model):
deployment_name = models.CharField(max_length=150, blank=True)
credentials = models.FileField(upload_to='media/credentials/', name='credentials'),
project_name = models.CharField(max_length=150, blank=True)
project_id = models.CharField(max_length=100, blank=False, name='project_id')
cluster_name = models.CharField(max_length=150, blank=False)
zone_region = models.CharField(max_length=150, blank=False)
services = models.CharField(max_length=100, choices=choices)
def __str__(self):
return self.deployment_name
class AwdModel(UserAccountModel):
source_zip = models.FileField(upload_to='media/awdSource/', name='awd_source')
routing = models.TextField(name='routing', null=True)
def __str__(self):
return self.deployment_name
def save(self, **kwargs):
if not self.id and self.services == 'Multiple' and not self.routing:
raise ValidationError("You must have to provide routing for multiple services deployment.")
super().save(**kwargs)
# def clean(self):
# if self.services == 'Multiple' and self.routing is None:
# raise ValidationError('You must have to provide routing for multiple services deployment.')
class AwodModel(UserAccountModel):
source_zip = models.FileField(upload_to='media/awodSource/', name='awod_source')
routing = models.TextField({'type': 'textarea'}, name='routing')
def save(self, **kwargs):
if not self.id and self.services == 'Multiple' and not self.routing:
raise ValidationError("You must have to provide routing for multiple services deployment.")
super().save(**kwargs)
I need to serialize these models, Here's how I have implemented serializers for these models:
from rest_framework import serializers
from .models import UserAccountModel, AwdModel, AwodModel
class UserAccountSerializer(serializers.ModelSerializer):
class Meta:
model = UserAccountModel
fields = ('deployment_name', 'credentials', 'project_name',
'project_id', 'cluster_name', 'zone_region', 'services')
class AWDSerializer(serializers.ModelSerializer):
class Meta(UserAccountSerializer.Meta):
model = AwdModel
fields = UserAccountSerializer.Meta.fields + ('awd_source', 'routing',)
class AWODSerializer(serializers.ModelSerializer):
class Meta:
model = AwodModel
fields = '__all__'
But, when I try to access, AWDSerialzer it return an error as:
AttributeError at /api/v1/deployments/
Got AttributeError when attempting to get a value for field project_id on serializer AWDSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the QuerySet instance.
Original exception text was: 'QuerySet' object has no attribute 'project_id'.
Update: Here's my APIView code:
class DeploymentsList(APIView):
def get(self, request):
MAX_OBJECTS = int(20)
deployments = AwdModel.objects.all()[:MAX_OBJECTS]
data = AWDSerializer(deployments).data
return Response(data)
class DeploymentDetail(APIView):
def get(self, request, *args, **kwargs):
deployment = get_object_or_404(AwdModel, pk=kwargs['pk'])
data = AWDSerializer(deployment).data
return Response(data)
Help me, please!
Thanks in advance!
AttributeError at /api/v1/deployments/ Got AttributeError when
attempting to get a value for field project_id on serializer
AWDSerializer. The serializer field might be named incorrectly and not
match any attribute or key on the QuerySet instance. Original
exception text was: 'QuerySet' object has no attribute 'project_id'.
This is an attribute error, when attempting to get the value from field project_id .
Get rid of the name attribute in the project_id field.
Edit The APIView code
To serialize a queryset or list of objects instead of a single object
instance, you should pass the many=True flag when instantiating the
serializer. You can then pass a queryset or list of objects to be
serialized. [Serializing multiple objects]
class DeploymentsList(APIView):
def get(self, request):
MAX_OBJECTS = int(20)
deployments = AwdModel.objects.all()[:MAX_OBJECTS]
data = AWDSerializer(deployments, many=True).data
return Response(data)
I hope this will help.
The code that you posted appears to be valid and correct. The issue however is unrelated. The exception text 'QuerySet' object has no attribute 'project_id' Refers to an issue that likely originates from your restframework app's views.py file. The exception states that you are attempting to access the attribute 'project_id' from a QuerySet.
A QuerySet is a (lazy loaded) set of models and not a single model. Even if the query set had only one element you'd still be required to access that element before accessing it's attributes.
Because you haven't shared your views.py file I can't say for sure where the issue is however here is an incorrect use case example: MyModel.objects.all().project_id. Here we can see that I am attempting to access the attribute project_id from a query set. A correct use case would be MyModel.objects.all()[0].project_id. However this assumes that the query set is not empty.
Practically, most DjangoRestFramework views inherit from rest_framework.views.APIView which subclasses django's View Class. I would suggest checking the query_set within that class is being used correctly.
Feel free to share your implementation here for further comment.
[EDIT] - After views.py coded was added.
You are attempting to serializer an entire query set with the instantiation of a serializer data = AWDSerializer(deployments).data this is causing the attribute error.
I would recommend the generics.ListAPIView class and the use of the class attributes query_set and serializer_class. These are simple to implement. You can then invoke the APIViews default get method. Here is an example for your DeploymentsList view
from rest_framework import generics
class DeploymentsList(generics.ListAPIView):
serializer_class = AWDSerializer
queryset = AwdModel.objects.all()
def get(self, request, *args, **kwargs):
MAX_OBJECTS = int(20)
self.queryset = self.queryset[:MAX_OBJECTS]
return super(DeploymentsList, self).get(request, *args, **kwargs)
[EDIT] - FileField Serialization
In order to serialize the UserAccount.credentials file field so that we serializer the path, we can use the serializers.SerializerMethodField. I.e Your UserAccountSerializer becomes:
class UserAccountSerializer(serializers.ModelSerializer):
credentials = serializers.SerializerMethodField()
def get_credentials(self, user_account):
return user_account.credentials.path
class Meta:
model = UserAccountModel
fields = ('deployment_name', 'credentials', 'project_name',
'project_id', 'cluster_name', 'zone_region', 'services')
When you inherit from a model class which is not defined as abstract in it’s own meta class, then Django creates a one-to-one relation between the subclass and its parent. Which actually creates two tables in the database; one for the base class and one for the subclass.
I haven’t tried your code, nor used Django 2, but would check using a relational field between the two serializer.

DRF #property field serializer Got AttributeError when attempting to get a value for field X on serializer Y

I'm using django rest framework for serialize and update a #property field, but i'm getting the error:
AttributeError: Got AttributeError when attempting to get a value for field `template` on serializer `PublicationSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Publication` instance.
Original exception text was: 'NoneType' object has no attribute 'template'.
i have the following models:
class Publication(models.Model):
#property
def template(self):
return self.apps.first().template
class App(models.Model):
publication = models.ForeignKey(Publication, related_name='apps')
template = models.ForeignKey(Template, blank=True, null=True)
class Template(models.Model):
name = models.CharField(_('Public name'), max_length=255, db_column='nome')
and the following serializer:
class PublicationSerializer(serializers.ModelSerializer):
template = TemplateSerializer(read_only=False)
class Meta:
model = models.Publication
fields = ('template',)
def update(self, instance, validated_data):
template_data = validated_data.pop('template', None)
instance = super().update(instance, validated_data)
if template_data:
instance.apps.all().update(template__id=template_data['id'])
return instance
This error happens when i use GET method to view and my Publication.apps is empty, and when i try to use POST method, i receive an empty OrderedDict() object.
This looks like when my field is null the DRF can't discover field type, and when my i try to POST the serializer isn't working as well...
Looks like publication you are trying to use don't have related apps. That's why self.apps.first() return None and self.apps.first().template raise exception. Try to change property to this:
#property
def template(self):
return getattr(self.apps.first(), 'template', None)

Categories

Resources