I'm beginner in python and Django rest And I stuck when I fetch data.
Here is my API :- http://127.0.0.1:8000/subjects/course/23/
I want a all subject data according to course which I select..When I hit this api if single data present working awesome but when inside course_id multiple subject present then gives me error such as :
Exception Type: MultipleObjectsReturned
Exception Value: get() returned more than one Subject -- it returned 2!
Here is my model.py
class Subject(models.Model):
course = models.CharField(max_length=255, blank=False, unique=False)
subject = models.CharField(max_length=255, blank=False, unique=False)
description = models.CharField(max_length=255, blank=False, unique=False)
amount = models.CharField(max_length=255, blank=False)
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
def __str__(self):
return "{}".format(self.title)
Here is my serializer.py
class SubjectSerializer(serializers.ModelSerializer):
class Meta:
model = Subject
fields = ('id', 'course', 'subject', 'description', 'amount', 'date_created', 'date_modified')
read_only_fields = ('date_created', 'date_modified')
lookup_field = 'course'
Here is my views.py
class ViewSubjectAccordingCourse(generics.RetrieveUpdateDestroyAPIView):
"""This class handles the GET and POSt requests of our rest api."""
queryset = Subject.objects.all()
serializer_class = SubjectSerializer
lookup_field = 'course'
Here is my urls.py
url(r'^subjects/course/(?P<course>[0-9]+)/$', ViewSubjectAccordingCourse.as_view(), name="details"),
so the problem is
course = models.CharField(max_length=255, blank=False, unique=False)
this value is identical for more then one subject, as you send in unique=False this seems to be by design, is the plan to have one or more subjects per course?
If its meant to be many subjects, you need to use the ListAPIView and some get_queryset modifications. If course is ment to only have a single Subject then change the field to unique=True
Related
models
class CreatorRawArtwork(models.Model):
id = models.AutoField(primary_key=True)
title = models.CharField(max_length=500)
descripton = models.TextField()
editions = models.IntegerField(null=True, blank=True)
price = models.CharField(max_length=500)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
medias = models.FileField(null=True, blank=True, upload_to="raw-medias")
user = models.ForeignKey(to=Login, on_delete=models.CASCADE, related_name="creatorrawartwork", null=True, blank=True
)
collection = models.ForeignKey(
to=DesignerCollection, on_delete=models.CASCADE, related_name="creatorrawartwork", null=True, blank=True)
categories = models.ManyToManyField(DesignerCategories, related_name='creatorrawartwork')
def __str__(self):
return self.title
serializer
class CreatorRawArtworkSerializer(serializers.ModelSerializer):
categories = serializers.PrimaryKeyRelatedField(queryset=DesignerCategories.objects.all(), many=True)
class Meta:
model = CreatorRawArtwork
fields = "__all__"
depth=1
views
class CreatorRawArtworkView(viewsets.ModelViewSet):
queryset = CreatorRawArtwork.objects.all()
serializer_class = CreatorRawArtworkSerializer
Here i am trying to create manytomany fields using drf serialier it is showing some error
plese check the screenshot for parameter and responses
What can be the issue please take a look
class CreatorRawArtworkSerializer(serializers.ModelSerializer):
collection = DesignerCollectionSerializer(read_only=True) #assuming you have already defined serializer for *DesignerCollectionSerializer*
categories = DesignerCategoriesSerializer(many=True)
class Meta:
model = CreatorRawArtwork
fields = "__all__"
depth=1
I tested with your code and your code is working fine
just make sure your request data is json
I need your help, is really basic.
I have two models, Autor and Post with a many to one relationship. I'm having problems retrieving the data in the html page. What I want to do is list all the posts for a specific Autor within a FOR and besides that I need to show the first name and last name of the autor out of the FOR.
I really appreciate your help.
class Autor(models.Model):
first_name = models.CharField(max_length=30, null=False, verbose_name='First Name')
last_name = models.CharField(max_length=30, null=False, verbose_name='Last Name')
def __str__(self):
return self.first_name
class Meta:
db_table = 'autor'
verbose_name = 'Autor'
verbose_name_plural = 'Autors'
ordering = ['id']
class Post(models.Model):
autor = models.ForeignKey(Autor, on_delete=models.CASCADE)
post = models.CharField(max_length=200, null=False, verbose_name='Post')
def __str__(self):
return self.post
class Meta:
db_table = 'post'
verbose_name = 'Post'
verbose_name_plural = 'Posts'
ordering = ['id'] ```
Since you don't specify a related_name attribute in ForeignKey definition, Django automatically creates a related_name using the name of your model with the suffix _set, for example, if sample_author is an instance of Author, this query returns all posts of the sample_author:
author_posts = sample_author.post_set.all()
then you can use all posts that exist in the result of this query within a FOR loop.
for post in author_posts:
do something
outside of this loop, you can access to first_name and last_name of the sample_author instance by sample_author.first_name and sample_author.last_name
.
I have problem with Django restframe work i have 2 table that one of them is a foreign key to another i have used RelatedField in serializer but i get an error:'Relational field must provide a queryset argument,
can someone help me in this case
my code is as below:
class DocTable(models.Model):
project = models.CharField(max_length=1000, null=True, blank=True)
document_no = models.CharField(max_length=1000, null=True, blank=True)
document_title = models.TextField(null=True, default='', blank=True)
class PlanTable(models.Model):
document = models.ForeignKey(DocTable, on_delete=models.CASCADE, related_name='doctable')
work_type = models.CharField(max_length=1000, null=True, blank=True)
description_work = models.TextField(null=True, default='', blank=True)
serializers.py
class DocTableSerializer(serializers.ModelSerializer):
doctable = serializers.RelatedField(many=True)
class Meta:
model = DocTable
fields = ['pk', 'project', 'document_no', 'doctable']
read_only_fields = ['pk']
class PlanTableSerializer(serializers.ModelSerializer):
class Meta:
model = PlanTable
fields = ['pk', 'document', 'work_type', 'description_work']
read_only_fields = ['pk']
views.py
class DocTableListView(generics.ListAPIView):
lookup_field = 'pk'
serializer_class = DocTableSerializer
def get_queryset(self):
return PlanTable.objects.all()
def get_object(self):
pk = self.kwargs.get('pk')
return PlanTable.objects.get(pk=pk)
You have to provide queryset in RelatedField like this.
class DocTableSerializer(serializers.ModelSerializer):
doctable = serializers.RelatedField(many=True, queryset=DocTable.objects.all())
Or if you only want to use this related field for retrieving data, you can mark it as read only
doctable = serializers.RelatedField(many=True, read_only=True)
I have a model Workflow and WorkflowLevel. Each workflow has many WOrkflow levels .Im trying to use nested serializer :
class WorkflowLevelSerializer
(serializers.ModelSerializer):
class Meta:
model = WorkflowLevel
fields = '__all__'
class
WorkflowSerializer
(serializers.ModelSerializer):
levels = WorkflowLevelSerializer(many=True)
class Meta:
model = Workflow
fields = ('id', 'name', 'description',
'tenant', 'levels')
models.py:
class Workflow(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=32, default=None, null=True)
description = models.CharField(max_length=100, default=None, null=True)
tenant = models.ForeignKey(Tenant, on_delete=models.CASCADE, default=None,
null=False)
class Meta:
unique_together = ('name', 'tenant',)
class WorkflowLevel(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE,
default=None, null=False)
level = models.IntegerField(default=None, null=False)
operation = models.CharField(max_length=32, default=None, null=False)
class Meta:
unique_together = ('workflow', 'level',)
The levels field is not displaying in the workflow listAPI view .
Getting error:
Got AttributeError when attempting to get a value
for field `levels` on serializer
`WorkflowSerializer`.
The serializer field might be named incorrectly
and not match any attribute or key on the
`Workflow` instance.
Original exception text was: 'Workflow' object
has no attribute 'levels'.
You can define related_name in the Model like this:
workflow = models.ForeignKey(Workflow, on_delete=models.CASCADE, related_name="levels", default=None, null=False)
I am using related_name='levels', so that in Serializer, it will use that reverse relationship name to fetch WorkflowLevel data from db.
I have 2 models here Tag and Question. All i want is to serialize the Tag Model without explicitly inside the Question Serializer where Tag model is related by ManyToMany relation with Question model.
class Question(models.Model):
question = models.TextField(blank=False, null=False)
question_image = models.ImageField(blank=True, null=True, upload_to='question')
opt_first = models.CharField(max_length=50, blank=False, null=False)
opt_second = models.CharField(max_length=50, blank=False, null=False)
opt_third = models.CharField(max_length=50, blank=False, null=False)
opt_forth = models.CharField(max_length=50, blank=False, null=False)
answer = models.CharField(max_length=1, choices=(('1','1'),('2','2'),('3','3'),('4','4')))
description = models.TextField(blank=True,null=True )
tag = models.ManyToManyField(Tag)
created_on = models.DateTimeField(default= timezone.now)
class Tag(models.Model):
name = models.CharField(max_length = 50, null=False, unique=True)
And I have serializers classes for these two models
class TagSerializer(serializers.ModelSerializer):
class Meta:
model = Tag
fields = ('name',)
class QuestionSerializer(serializers.ModelSerializer):
# tag = TagSerializer(many=True)
def to_representation(self, obj):
rep = super(QuestionSerializer, self).to_representation(obj)
rep['tag'] = []
for i in obj.tag.all():
# rep['tag'].append({'id':i.id,'name':i.name})
# Below doesn't give JSON representation produces an error instead
rep['tag'].append(TagSerializer(i))
return rep
class Meta:
model = Question
fields = ('question', 'question_image', 'opt_first', 'opt_second', 'opt_third', 'opt_forth', 'answer', 'description', 'tag')
read_only_fields = ('created_on',)
Here on using TagSerializer in the to_repesentation method of QuestionSerializer doesn't serialize the tag object. Instead produces error
ExceptionValue : TagSerializer(<Tag: Geography>):
name = CharField(max_length=50, validators=[<UniqueValidator(queryset=Tag.objects.all())>]) is not JSON serializable
You are trying to serialize TagSerializer class. Try to change code to serialize data:
for i in obj.tag.all():
# rep['tag'].append({'id':i.id,'name':i.name})
# Below doesn't give JSON representation produces an error instead
ser = TagSerializer(i)
rep['tag'].append(ser.data)
Also I didn't get why you are override to_representation method.
Try just to define tag field in QuestionSerializer:
tag = TagSerializer(read_only=True, many=True)