When I try to retrieve all data from my REST API I get them correctly except from one field, that is the field 'name' from Skill class. Instead of the 'name' I get only its id. Can you help me to resolve this?----------------------------------------------
here is the output Here is the code:
models.py
from django.db import models
from django.forms import ImageField
from django.utils.text import slugify
class Skill(models.Model):
name = models.CharField(max_length=200)
def __str__(self):
return self.name
class Project(models.Model):
title = models.CharField(max_length=200)
sub_title = models.CharField(max_length=200, null=True, blank=True)
front_page = models.ImageField(null=True, blank=True, upload_to="images", default="broken-image.png")
body = models.TextField(null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
skills = models.ManyToManyField(Skill, null=True)
slug = models.SlugField(null=True, blank=True)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
if self.slug == None:
slug = slugify(self.title)
has_slug = Project.objects.filter(slug=slug).exists()
count = 1
while has_slug:
count = 1
slug = slugify(self.title) '-' str(count)
has_slug = Project.objects.filter(slug=slug).exists()
self.slug = slug
super().save(*args, **kwargs)
serializers.py
from rest_framework import serializers
from project.models import Project, Skill
class ProjectSerializer(serializers.ModelSerializer):
class Meta:
model = Project
fields = '__all__'
views.py
from rest_framework.response import Response
from rest_framework.decorators import api_view
from project.models import Project, Skill
from .serializers import ProjectSerializer
from rest_framework import status
from django.shortcuts import get_object_or_404
@api_view(['GET'])
def getData(request):
project = Project.objects.all()
serializer = ProjectSerializer(project, many=True)
return Response(serializer.data)
@api_view(['POST'])
def create(request):
serializer= ProjectSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
@api_view(['POST'])
def update(request, pk):
item = Project.objects.get(pk=pk)
serializer = ProjectSerializer(instance=item, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
else:
return Response(status=status.HTTP_404_NOT_FOUND)
@api_view(['DELETE'])
def delete(request, pk):
item = get_object_or_404(Project, pk=pk)
item.delete()
return Response(status=status.HTTP_202_ACCEPTED)
urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.getData),
path('create/', views.create),
path('update/<int:pk>/', views.update),
path('<int:pk>/delete/', views.delete),
]
CodePudding user response:
You need to provide a SkillSerializer
and refer to it in your ProjectSerializer
. Also, it is better to specify the fields you want in your serializers explicitly, as __all__
may expose the fields you don't want to expose or cause unwanted database queries.
https://www.django-rest-framework.org/api-guide/relations/#nested-relationships
CodePudding user response:
Use a SlugRelatedField
[drf-doc] to specify that you want to use the name
of the skills, so:
from rest_framework import serializers
from project.models import Project, Skill
class ProjectSerializer(serializers.ModelSerializer):
skills = serializers.SlugRelatedField(
many=True, slug_field='name', queryset=Skill.objects.all()
)
class Meta:
model = Project
fields = '__all__'
The nice thing of such SlugRelatedField
is that this can work bidrectional: not only can you serialize data, but you can also use it to specify skills and thus create or update Project
s.