Django REST framework serializer for custom form data - python

I've started learning how to use the Django REST Framework along with React and I have a quick question. I made a form and use CreateAPIView and UpdateAPIView to create/update items, respectively. But how do I get the contents to populate my <select> field if the list comes from a variable in one of my models?
from model_utils import Choices
class Author(models.Model):
GENDER = Choices('male', 'female', "I don't know really") # How do I get this?
gender = models.CharField(max_length=10, choices=GENDER)
What will the serializer and views for Author.GENDER look like since it's not a model?
At the moment, this is what I have for now.
Django (nothing out of the ordinary here, I think.).
# Serializer.
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = ('id', 'gender')
# View
class AuthorUpdateView(UpdateAPIView):
queryset = Author.objects.filter(deleted_at__isnull=True)
serializer_class = AuthorSerializer
React.
componentDidMount() {
const pk = this.props.match.params.pk
axios.get(`http://localhost:8000/api/authors/${pk}`)
.then(response => {
const pk = response.data.id
const gender = response.data.gender
this.setState({gender})
})
.catch(err => console.log(err))
}
I'm open to any direction or concept you might have when using DRF so I can also learn from how you would do it.

Use viewset to combine the logic for a set of your related views (list, create, update)
class AuthorViewSet(ModelViewSet):
queryset = Author.objects.filter(deleted_at__isnull=True)
serializer_class = AuthorSerializer
Make a OPTIONS request to get the metadata for your resource, including the list of valid choices of gender field
Request
OPTIONS /api/authors/
Response
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"name": "Author List",
"parses": [
"application/json",
"application/x-www-form-urlencoded",
"multipart/form-data"
],
"actions": {
"POST": {
"id": {
"type": "integer",
"required": false,
"read_only": true,
"label": "Id"
},
"gender": {
"type": "choice",
"required": true,
"read_only": false,
"label": "Gender",
"choices": [
{
"value": "male",
"display_name": "male"
},
{
"value": "female",
"display_name": "female"
},
{
"value": "I don't know really",
"display_name": "I don't know really"
}
]
}
}
}
}

Related

django rest-framework API returns empty due to end operation how to solve it

I am building an API using django rest-framwork.
this is my data,
[
{
"id": 24,
"name": ""
},
{
"id": 45,
"name": "ADB"
},
{
"id": 2,
"name": "Agriculture"
},
{
"id": 27,
"name": "Category external workforce, professional and business services"
}]
it works fine if I provide a single item for the filter operation. like this.
http://127.0.0.1:8000/op-api/sec/?name=Agriculture
it returns me empty if I provide more then one item for the filtering purpose.
http://127.0.0.1:8000/op-api/sec/?name=Agriculture,ADB
but I want it should return data like this.
[
{
"id": 45,
"name": "ADB"
},
{
"id": 2,
"name": "Agriculture"
}
]
here is my code for the API
class sec_ViewSet(viewsets.ModelViewSet):
http_method_names = ['get']
serializer_class = sector_Serializer
filter_backends = [DjangoFilterBackend , SearchFilter , OrderingFilter]
filterset_fields = ['name',]
search_fields = ['name',]
def get_queryset(self) :
all_sec = Sector.objects.all()
return all_sec
class sector_Serializer(serializers.ModelSerializer) :
class Meta :
model = Sector
fields = ['id' , 'name']
how can I update it so that it works fine.

How to change what Django model returns as a value?

I'm trying to get my Product kind as what I declared It's name, instead I get number. Let me be more clear:
This below is my Product Kinds;
PRODUCT_KINDS = (
("1","Electronic"),
("2","Furniture"),
("3", "Bedroom"),
("4","Dining")
)
And this image below is my django-admin panel which everything seems perfect because I can get every single of my kinds.
However, when I try to get this data from api/products url I get this data
[
{
"image": null,
"name": "Headphones",
"kind": "1",
"price": 250.99,
"description": "No description for this item.",
"is_featured": true
},
{
"image": null,
"name": "Watch",
"kind": "3",
"price": 12.5,
"description": "No description for this item.",
"is_featured": true
},
{
"image": null,
"name": "T-shirt",
"kind": "2",
"price": 12.99,
"description": "No description for this item.",
"is_featured": true
},
{
"image": null,
"name": "Ali Ziya ÇEVİK",
"kind": "1",
"price": 1212.0,
"description": "No description for this item.",
"is_featured": false
}
]
as you can see In my django-admin panel I get the name of kind but In the API I get It's index.
This below is my serializer:
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
#kind = serializers.CharField(source = 'kind')
#print(kind)
class Meta:
model = Product
fields = ['image', 'name', 'kind',
'price', 'description', 'is_featured']
You could set source on value from Model.get_FOO_display() method
kind = serializers.CharField(source = 'get_kind_display')
You can try this use fields source with get_FOO_display :
https://docs.djangoproject.com/en/1.8/ref/models/instances/#django.db.models.Model.get_FOO_display
from rest_framework import serializers
from .models import Product
class ProductSerializer(serializers.ModelSerializer):
kind = serializers.CharField(source='get_kind_display')
class Meta(object):
model = Product
fields = ('image', 'name', 'kind','price', 'description', 'is_featured')

django taggit-serializer not create tags in rest framework

here is my models.py
class Post(models.Model):
author=models.ForeignKey(User,on_delete=models.CASCADE,related_name="post")
title=models.CharField(max_length=128,null=True,blank=True)
rate=models.IntegerField(validators=[MinValueValidator(1),MaxValueValidator(5)],default=True,null=True,blank=True)
# rating=models.IntegerField(null=True,blank=True)
content=models.TextField(null=True,blank=True)
review=models.CharField(max_length=250,null=True,blank=True)
url=models.URLField(null=True,blank=True)
voters = models.ManyToManyField(settings.AUTH_USER_MODEL,blank=True,related_name="post_voters")
tags = TaggableManager()
in my serializers.py
i have imported
from taggit_serializer.serializers import (TagListSerializerField,
TaggitSerializer)
and here is the post serializer
class Spost(serializers.ModelSerializer,TaggitSerializer):
tags = TagListSerializerField()
author=serializers.StringRelatedField(read_only=True)
# likes_count=serializers.SerializerMethodField(read_only=True)
# user_has_voted=serializers.SerializerMethodField(read_only=True)
## for string related field without displaying it as numerics , it displays the direct object of that object"
# user=Scomments()
class Meta:
model = Post
fields = ('id','title','rate','author','content','review','url','tags')
def get_likes_count(self,instance):
return instance.voters.count()
def get_user_has_voted(self,instance):
request=self.context.get("request")
return instance.voters.filter(pk=request.user.pk).exists()
but what issue i have been faceing right now is whenever i trigger a post request with tags the object is being created im getting that the object along with tags being created but when i see in the admin panel the tags part isnt being updated
{
"rate": 4,
"content": "content",
"review": "dsfdf",
"url": "http://google.com",
"tags": [
"django",
"python"
]
}
this is the post request and in postman i can see the updated request
{
"id": 122,
"title": null,
"rate": 4,
"author": "User",
"content": "content",
"review": "dsfdf",
"url": "http://google.com",
"tags": [
"django",
"python"
]
}
but when i see the same thing in django admin panel and json list of all objects i can see that tag part is blank
{
"id": 122,
"title": null,
"rate": 4,
"author": "User",
"content": "content",
"review": "dsfdf",
"url": "http://google.com",
"tags": []
}
class Spost(TaggitSerializer, serializers.ModelSerializer):
tags = TagListSerializerField()
Here You have to pass TaggitSerializer as the first argument in your serializer. As you are inheriting the TagListSerializerField field from it.

Django REST - How to create a non-model serializer?

Firstly I want to say I'm a newbie to Django.
I was wondering if is it possible to create a non-ModelSerializer which serialize existant model based serializers ?
In serializers.py, I already have this :
class MapSerializer(serializers.ModelSerializer):
class Meta:
model = Map
fields = ('id', 'name')
class GrenadeSerializer(serializers.ModelSerializer):
class Meta:
model = Grenade
fields = ('id', 'name')
I want here a new serializer which allows to display a JSON like that :
{
"maps": {
"map": [
{
"id": "1",
"name": "dust2"
},
{
"id": "2",
"name": "inferno"
}
]
},
"grenades": {
"grenade": [
{
"id": "1",
"name": "flashbang"
},
{
"id": "2",
"name": "smoke"
}
]
}}
I need something like this, even if I know the following structure isn't correct :
class MyNewSerializer(serializers.ModelSerializer):
maps = MapSerializer(many=True)
grenades = GrenadeSerializer(many=True)
class Meta:
field = ('maps', 'grenades')
Thanks in advance !

django rest framework: hypelinking referenced entitites

In my project i expose all BlogArticle entities via public API using Django rest framework.
Each BlogArticle ha an author field that refers to a Django user. I want this relations to be modeled using hyperlinks.
to achieve this i added:
in urls.py:
router = routers.DefaultRouter()
router.register(r'users', UserViewSet)
router.register(r'blogarticles', BlogArticleViewSet)
in views.py:
class UserViewSet(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
class BlogArticleViewSet(viewsets.ModelViewSet):
queryset = BlogArticle.objects.all()
serializer_class = BlogArticleSerializer
in serializers.py:
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'email', 'groups')
class BlogArticleSerializer(serializers.HyperlinkedModelSerializer):
author = serializers.HyperlinkedIdentityField(view_name='user-detail', format='json')
class Meta:
model = BlogArticle
fields = ('title', 'blog_content', 'author')
everything works correctly but not the hyperlink url.
The result is this:
HTTP 200 OK
Content-Type: application/json
Vary: Accept
Allow: GET, POST, HEAD, OPTIONS
{
"count": 21,
"next": "http://127.0.0.1:8000/api/blogarticles/?page=2",
"previous": null,
"results": [
{
"title": "text",
"blog_content": "content",
"author": "http://127.0.0.1:8000/api/users/1/"
},
{
"title": "boh",
"blog_content": "aa",
"author": "http://127.0.0.1:8000/api/users/2/"
},
[---]
First 2 BlogArticles apparently are written by 2 different users but the user is always the same(as conseguence by calling the second url i get a 404 response).
What i'm expecting is this:
HTTP 200 OK
Content-Type: application/json
Vary: Accept
Allow: GET, POST, HEAD, OPTIONS
{
"count": 21,
"next": "http://127.0.0.1:8000/api/blogarticles/?page=2",
"previous": null,
"results": [
{
"title": "text",
"blog_content": "content",
"author": "http://127.0.0.1:8000/api/users/1/"
},
{
"title": "boh",
"blog_content": "aa",
"author": "http://127.0.0.1:8000/api/users/1/"
},
[---]
When you need to hyperlink against related objects, you should use HyperlinkedRelatedField. When you need to hyperlink against the current object (the url field on the serializer), you should use HyperlinkedIdentityField.
class BlogArticleSerializer(serializers.HyperlinkedModelSerializer):
author = serializers.HyperlinkedRelatedField(view_name='user-detail', format='json')
class Meta:
model = BlogArticle
fields = ('title', 'blog_content', 'author')

Categories