I'm trying to create a ViewSet for the Course model (to simply display all courses), but I'm getting the following error when trying to access it. I'm new to creating ViewSets and Django in general, what am I doing wrong?
Django 2.2
Error
AttributeError: Got AttributeError when attempting to get a value for field `title` on serializer `CourseSerializer`.
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 'title'.
CourseViewSet
class CourseViewSet(viewsets.ModelViewSet):
def list(self, request):
queryset = Course.objects.all()
serializer = CourseSerializer(queryset)
return Response(serializer.data)
CourseSerializer
class CourseSerializer(serializers.ModelSerializer):
class Meta:
model = Course
fields = (
'id',
'title',
'description',
'active',
'individual_result',
'course_duration',
'video',
'manager_id'
)
models/Course
class Course(models.Model):
title = models.CharField(max_length=255, blank=False, null=False)
description = models.CharField(max_length=255, blank=True, null=True)
active = models.BooleanField(default=True)
individual_result = models.BooleanField(default=False)
course_duration = models.CharField(max_length=255, blank=True, null=True)
video = models.CharField(max_length=255, blank=True, null=True)
manager_id = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
def __str__(self):
return self.title
You should serialize with many=True, since a queryset is a collection of objects that can contain zero, one, or more elements:
serializer = CourseSerializer(queryset, many=True)
For more information, see the Dealing with multiple objects section [drf-doc].
Related
So I'm working on this project (an Inventory app). I have this model method I am trying to use in my View. I'm trying to call it in my view.
But I'm always getting an error: 'QuerySet' object has no attribute 'get_quantities_sold'
Here is my model:
generate_ref_no = str(uuid.uuid1())
class Transaction(models.Model):
business = models.ForeignKey(Business_Account, on_delete=models.CASCADE)
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True)
amount = models.FloatField()
productSold = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
quanties_of_product_sold = models.IntegerField()
transaction_date = models.DateTimeField(auto_now_add=True)
payment_method = models.CharField(choices=PAYMENT_METHOD, max_length=50)
reference_num = models.CharField(max_length=50, editable=False, default=generate_ref_no)
def __str__(self):
return f'{self.customer} '
def get_quantities_sold(self,quantities_sold):
return print(quantities_sold)
My view:
class TransactionView(generics.GenericAPIView):
def post(self,request, business=None):
serializer = TransactionSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
getTransaction = Transaction.objects.filter(reference_num=serializer.data['reference_num'])
getTransaction_serializer = TransactionSerializer(getTransaction, many=True)
getTransaction.get_quantities_sold(serializer.data['quanties_of_product_sold '])
return Response(data=serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(data=serializer.errors, status=status.HTTP_404_NOT_FOUND)
I'm trying to call the 'get_quantities_sold' method from the Transaction model in my transaction view but I'm an error: QuerySet' object has no attribute 'get_quantities_sold'
getTransaction is in your method is a QuerySet and thus a collection of items, not a single item, hence getTransaction.get_quantities_sold makes no sense. You can retrieve a single Transaction object by using .get(…) [Django-doc] over .filter(…) [Django-doc]:
getTransaction = Transaction.objects.get(
reference_num=serializer.data['reference_num']
)
It might also be worth to guarantee uniqueness for the reference_num with:
reference_num = models.CharField(
max_length=50,
editable=False,
default=generate_ref_no,
unique=True
)
I created a model for Slide on django. below is model.py
class Slide(models.Model):
user = models.ForeignKey(User, on_delete=models.DO_NOTHING, blank=True)
text = models.CharField(max_length=300)
is_deleted = models.BooleanField(default=False)
topic_id = models.ForeignKey(Article, on_delete=models.DO_NOTHING)
created_at = models.DateTimeField("created at", auto_now_add=True)
objects = models.Manager()
def __str__(self):
return self.text
serializer.py
class SlideSerializer(serializers.ModelSerializer):
topicdetail_set = ArticleDetailSerial(many=True)
user_detail = FindOwnerSerializer(source='user', read_only=True)
author = AuthorSerializer(many=True)
class Meta:
model = Slide
fields = ('id','text', 'created_at', 'topicdetail_set', 'user_detail','author')
When I run the url for slide http://127.0.0.1:8000/article/slide/
then I got below error
AttributeError: Got AttributeError when attempting to get a value for field `topicdetail_set` on serializer `SlideSerializer`.
The serializer field might be named incorrectly and not match any attribute or key on the `Slide` instance.
Original exception text was: 'Slide' object has no attribute 'topicdetail_set'.
Now I am confused, Is the code that I have created is wrong? And if it is wrong then how should I fix it?
Can anyone explain about the problem.
mobel.py
class Blog(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField(max_length=120, null=True, blank=True)
content = models.TextField(null=True, blank=True)
timestamp = models.DateTimeField(auto_now_add=True)
def get_api_url(self):
return api_reverse("post-rud", kwargs={"pk": self.pk})
and my serializer file is serializer.py
class BlogSerializers(serializers.ModelSerializer):
uri = serializers.SerializerMethodField(read_only=True)
class Meta:
model = Blog
fields = [
'uri',
'pk',
'user',
'title',
'content',
'timestamp',
]
read_only_fields = ['pk', 'user']
def get_uri(self, obj):
return obj.get_api_url()
error showing
AttributeError at /api/blog/post/list/ 'BlogSerializers' object has no
attribute 'get_uri'
if i use under this line than problem is solved. But i wanna understand about this error.
class BlogSerializers(serializers.ModelSerializer):
# uri = serializers.CharField(read_only=True, source='get_api_url')
You added the get_uri method to the meta Class, instead of your serializer class.
Just remove one indentation level and you are good to go.
In my Django REST framework project i have this model:
class ml_request(models.Model):
model_id = models.CharField(max_length=100)
created = models.DateTimeField(auto_now=True)
p_country = models.CharField(max_length=100, blank=False, default='')
p_description = models.TextField(null=False, blank=False)
p_designation = models.CharField(max_length=200, blank=False, default='')
p_points = models.IntegerField(default=00)
p_price = models.IntegerField(default=00, blank=False)
p_province = models.CharField(max_length=100, blank=False, default='')
p_region_1 = models.CharField(max_length=100, blank=False, default='')
p_region_2 = models.CharField(max_length=100, blank=False, default='')
p_variety = models.CharField(max_length=100, blank=False, default='')
p_winery = models.CharField(max_length=100, blank=False, default='')
owner = models.ForeignKey('auth.User', related_name='req_owner',
on_delete=models.CASCADE)
highlighted = models.TextField()
class Meta:
ordering = ('created',)
then i create my serializer like this:
from rest_framework import serializers
from botoapi.models import ml_request, ml_response, LANGUAGE_CHOICES,
STYLE_CHOICES, ml_logs
from django.contrib.auth.models import User
class RequestSerializer(serializers.HyperlinkedModelSerializer):
id = serializers.IntegerField(label='ID', read_only=True)
highlight = serializers.HyperlinkedIdentityField(view_name='request-highlight', format='html')
owner = serializers.ReadOnlyField(source='owner.username')
class Meta:
model = ml_request
fields = ('id', 'model_id', 'highlight', 'created', 'p_country',
'p_description', 'p_designation',
'p_points', 'p_price', 'p_province', 'p_region_1', 'p_region_2',
'p_variety', 'p_winery', 'owner')
def create(self, validated_data):
log_save = ml_logs(l_verbose=validated_data, l_method="CREATE",
l_action=validated_data.get("model_id", None))
log_save.save()
return validated_data
and is my view code:
class RequestViewSet(viewsets.ModelViewSet):
queryset = ml_request.objects.all()
serializer_class = RequestSerializer
permission_classes = (IsAuthenticatedOrReadOnly,
IsOwnerOrReadOnly,)
#detail_route(renderer_classes=[renderers.StaticHTMLRenderer])
def highlight(self, request, *args, **kwargs):
snippet = self.get_object()
return Response(snippet.highlighted)
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
bur when i run it and try to add values django return this error:
AttributeError at /requests/
'dict' object has no attribute 'pk'
Request Method: POST
Request URL: http://127.0.0.1:8000/requests/
Django Version: 1.11.7
Exception Type: AttributeError
Exception Value:
'dict' object has no attribute 'pk'
i have the id as PK and i add it in my serializer, someone can help me to wonder why this happens?
Thanks in advance
From 3.x onwards,
If you want to add django auto 'id' explicitly in HyperlinkedModelSerializer, you need to use ReadOnlyField (not an IntegerField). Or else you can include it in 'fields'.
class RequestSerializer(serializers.HyperlinkedModelSerializer):
id = serializers.ReadOnlyField()
And by default the serializer will include a url field instead of a primary key field. You can explicitly include the primary key by adding it to the fields option.
The name of the URL field defaults to 'url'. You can override this
globally, by using the URL_FIELD_NAME setting.
I have the following model structure:
class Project(models.Model):
author = models.ManyToManyField(Account)
name = models.CharField(max_length=40, default='NewBook')
class Account(AbstractBaseUser):
email = models.EmailField(unique=True)
username = models.CharField(max_length=40, unique=True)
first_name = models.CharField(max_length=40, blank=True)
last_name = models.CharField(max_length=40, blank=True)
tagline = models.CharField(max_length=140, blank=True)
is_admin = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = AccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
My view looks like this:
class ProjectViewSet(viewsets.ModelViewSet):
queryset = Project.objects.order_by('-name')
serializer_class = ProjectSerializer
def perform_create(self, serializer):
instance = serializer.save(author=self.request.user)
return super(ProjectViewSet, self).perform_create(serializer)
After calling the view function, a classifier gets created in the database. But after that, I get the following error:
TypeError: 'Account' object is not iterable
The error gets thrown in this line:
instance = serializer.save(author=self.request.user)
Anyone how can help me with this?
There are two problems here:
Showing nested relationships for M2M field:
If the field is used to represent a to-many relationship, you should add the many=True flag to the serializer field.
So you need to add many=True to AccountSerializer:
author = AccountSerializer(read_only=True, required=False, many=True)
A writable nested serializer:
By default nested serializers are read-only. If you want to support write-operations to a nested serializer field you'll need to create create() and/or update() methods in order to explicitly specify how the child relationships should be saved.
So if you look at the example and the documentation it seems that you need to implement create or update method.
You need to set many=True when dealing with multiple relation - either a m2m or a reversed FK:
author = AccountSerializer(read_only=True, required=False, many=True)
Since your Author field is many to many, you will need to override the create method on your serializer.
def create(self, validated_data):
author = validated_data.pop(author, None)
project = Project.objects.save(validated_data)
if author:
project.author.add(author)
You will also probably need to set the update method on the serializer, the behavior here can be tricky so make sure you test and make sure the behavior is what you expect.
Ok, my previous answer, though could be an issue, isn't the root cause of the actual crash.
When calling the serializer, you set:
instance = serializer.save(author=self.request.user)
However, author is a ManyToManyField which means you should call the serializer as:
instance = serializer.save(author=[self.request.user])
NB: you still require the many=True on the serializer's author field.
Please check...
your model.py
class Account(AbstractBaseUser):
email = models.EmailField(unique=True)
username = models.CharField(max_length=40, unique=True)
first_name = models.CharField(max_length=40, blank=True)
last_name = models.CharField(max_length=40, blank=True)
tagline = models.CharField(max_length=140, blank=True)
is_admin = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = AccountManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
class Project(models.Model):
author = models.ManyToManyField(Account)
name = models.CharField(max_length=40, default='NewBook')
your serializer.py
class ProjectSerializer(serializers.ModelSerializer):
author = AccountSerializer(read_only=True, required=False)
class Meta:
model = Project
fields = ('id', 'author', 'name')
read_only_fields = ('id')
def get_validation_exclusions(self, *args, **kwargs):
exclusions = super(ProjectSerializer, self).get_validation_exclusions()
return exclusions + ['author']
and finally your view.py is
class ProjectViewSet(viewsets.ModelViewSet):
queryset = Project.objects.order_by('-name')
serializer_class = ProjectSerializer
def perform_create(self, serializer):
instance = serializer.save(author=self.request.user)
return super(ProjectViewSet, self).perform_create(serializer)