django rest framework error while post through json data - python

here is my models.py
from __future__ import unicode_literals
from django.db import models
class User(models.Model):
name = models.CharField(max_length=200)
company_name = models.ForeignKey('Company',on_delete=models.CASCADE,related_name='user')
def __str__(self):
return self.name
class Company(models.Model):
name = models.CharField(max_length=200)
phone_number = models.IntegerField(null=True,blank=True)
def __str__(self):
return self.name
class Catalog(models.Model):
name = models.CharField(max_length=200)
no_of_pcs = models.IntegerField(null=True,blank=True)
per_piece_price = models.DecimalField(null=True,blank=True,max_digits=10,decimal_places=2)
company_name = models.ForeignKey(Company,on_delete=models.CASCADE,related_name='catalog')
def __str__(self):
return self.name
Here is my serializers.py
from rest_framework import serializers
from .models import *
from django.db.models import Sum,Count
class CatalogSerializerPost(serializers.Serializer):
id = serializers.IntegerField()
name = serializers.CharField(required=False, allow_blank=True, max_length=100)
no_of_pcs = serializers.IntegerField()
per_piece_price = serializers.IntegerField()
def create(self, validated_data):
return Catalog.objects.create(**validated_data)
class CatalogSerializer(serializers.ModelSerializer):
total_pieces = serializers.SerializerMethodField()
total_price = serializers.SerializerMethodField()
class Meta:
model = Catalog
fields = ('name','no_of_pcs','per_piece_price','company_name','total_pieces','total_price')
depth = 1
def get_total_pieces(self, obj):
totalpieces = Catalog.objects.aggregate(total_pieces=Count('no_of_pcs'))
return totalpieces["total_pieces"]
def get_total_price(self, obj):
totalprice = Catalog.objects.aggregate(total_price=Sum('per_piece_price'))
return totalprice["total_price"]
here is my views.py
from __future__ import unicode_literals
from django.http import HttpResponse
from .models import *
import json
from django.http import JsonResponse, HttpResponse
from .serializers import *
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import viewsets, generics
from rest_framework.decorators import api_view
#api_view(['GET', 'POST'])
def CatalogView(request):
if request.method == 'GET':
catalogs = Catalog.objects.select_related('company_name')
serializer = CatalogSerializer(catalogs, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = CatalogSerializerPost(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
Here is my urls.py
from django.conf.urls import url, include
from django.contrib import admin
from api.views import CatalogView
from api import views
from rest_framework.urlpatterns import format_suffix_patterns
from rest_framework import routers
router = routers.DefaultRouter()
# router.register('catalogs',views.CatalogView,'catalog')
router.register('companies',views.CompanyView)
router.register('users',views.UserView)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include(router.urls)),
url(r'catalog/', CatalogView),
]
Here i am not able to post data THRIUGH JSON DATA..
Please refer the screenshot for the error..
Thanks..
here is the screen shot for error
please check this issue.
Here i am not able to post data THROUGH JSON DATA..
showing id field is required.

there are few problems with your Serializer and View both, and also the data that you are passing, Change your serializer to this
class CatalogSerializerPost(serializers.Serializer):
name = serializers.CharField(required=False, allow_blank=True, max_length=100)
no_of_pcs = serializers.IntegerField()
per_piece_price = serializers.IntegerField()
company_name_id = serializers.IntegerField() # add this field as you have a company field in the Catalog Model. and you are passing company id in the JSON.
def create(self, validated_data):
return Catalog.objects.create(**validated_data)
and pass
"company_name_id" :3 in your json

You need to mark id field as read only:
class CatalogSerializerPost(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
Also it could be more simple to use ModelSerializer.

Related

Django form not sending data to admin

I have a form users can fill out to reserve a table at a restaurant. However when they submit the form no data gets sent to the admin side.
I have watched some tutorials and read other posts on this site and nothing seems to fix it. I feel like it is something so small but I just cant figure it out.
views.PY
from django.shortcuts import render, get_object_or_404
from django.views import generic, View
from .models import Book
from .forms import BookForm
from django.http import HttpResponseRedirect
def Book(request):
"""
Renders the book page
"""
if request.user.is_authenticated:
form = BookForm(request.POST or None)
context = {
"form": form,
}
else:
return HttpResponseRedirect("accounts/login")
book_form = BookForm(data=request.POST)
if book_form.is_valid():
instance = book_form.save(commit=False)
instance.save()
else:
book_form = BookForm()
return render(
request,
"book.html",
{
"book_form": BookForm(),
}
)
models.py
from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MinValueValidator
from cloudinary.models import CloudinaryField
class Book(models.Model):
name = models.CharField(max_length=50)
number_of_guests = models.PositiveIntegerField(validators=[MinValueValidator(1)])
date = models.DateTimeField()
email = models.EmailField()
requests = models.TextField(max_length=200)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
approved = models.BooleanField(default=False)
class Meta:
ordering = ['date']
def __str__(self):
return f"{self.date} for {self.name}"
forms.py
from .models import Book
from django import forms
class BookForm(forms.ModelForm):
class Meta:
model = Book
fields = (
'name',
'number_of_guests',
'date',
'email',
'requests',
)
Try this view:
from django.contrib.auth.decorators import login_required
from django.shortcuts import redirect,render
#login_required(login_url="accounts/login")
def Book(request):
if request.method=="POST":
book_form = BookForm(request.POST)
if book_form.is_valid():
book_form.save()
return redirect("some_success_page")
else:
return redirect("some_error_page")
else:
book_form = BookForm()
return render(
request,
"book.html",
{
"book_form": book_form,
}
)
In settings.py
LOGIN_URL="accounts/login"

AttributeError: Got AttributeError when attempting to get a value for field `comments` on serializer `Post`

**In my blog app when i used to retrive all the posts I got this error.
**
This is the error message I got:
AttributeError: Got AttributeError when attempting to get a value for field comments on serializer Post.
The serializer field might be named incorrectly and not match any attribute or key on the Post instance.
Original exception text was: 'Post' object has no attribute 'comments'.
I attached my code below. Help me how to get rid out of this.
models.py
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.contrib.auth.models import User
#Abstract Start
class TimeStamp(models.Model):
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Selection(TimeStamp):
name = models.CharField(max_length=100)
class Meta:
abstract = True
ordering = ['name']
#Abstract End
class Post(Selection):
# name = title
author = models.ForeignKey(User,on_delete=models.CASCADE)
body = models.TextField(_("content"))
slug = models.SlugField(_("slug"))
likes = models.IntegerField(_("likes"),default=0)
def __str__(self):
return self.name
class Comment(TimeStamp):
user = models.ForeignKey(User,on_delete=models.CASCADE)
content = models.TextField(_("comments"))
likes = models.IntegerField(_("likes"),default=0)
post = models.ForeignKey(Post,on_delete=models.CASCADE)
def __str__(self):
return self.content
serializers.py
from django.contrib.auth.models import User
from rest_framework import serializers
from . import models
class UserSr(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id', 'username', 'email')
class Comment(serializers.ModelSerializer):
user = UserSr()
class Meta:
model = models.Comment
exclude = ['created_at','updated_at']
class Post(serializers.ModelSerializer):
author = UserSr()
comments = Comment(many = True)
class Meta:
model = models.Post
exclude = ['created_at','updated_at']
views.py
from django.contrib.auth.models import User
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .. import serializers,models
#api_view(['POST'])
def post_create(request):
post_serializer = serializers.Post(data=request.data)
if post_serializer.is_valid():
post_serializer.save()
return Response(post_serializer.data, status=status.HTTP_201_CREATED)
return Response(post_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
#api_view(['GET'])
def postGet(request):
posts = models.Post.objects.all()
serializer = serializers.Post(posts,many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
urls.py
from django.urls import path
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
from . import views
urlpatterns = [
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
path("blog/",views.registration_view,name='useradd'),
path('posts/',views.postGet,name='posts'),
path('posts/create/', views.post_create, name='post-create'),
]
I don't know how to get rid out of this
I've stucked it in for hours.
I refered lot of projects but i could not figure it out.
class Post(serializers.ModelSerializer):
author = UserSr()
comments = serializers.StringRelatedField(many=True)
class Meta:
model = models.Post
fields = ("id","author","comments")
You can try this.
You should not use Comment a model in Serializers as a field

Django view get() takes 1 positional argument but 2 were given

I am making API with Django.
Crawled data is saved well in DB, but I have a problem with making API.
views.py
from django.shortcuts import render
from rest_framework.response import Response
from .models import ReviewData
from .models import BuildingData
from rest_framework.views import APIView
from .serializers import ReviewSerializer
from .serializers import BuildingSerializer
from django.shortcuts import render, get_object_or_404
class BuildingInfoAPI(APIView):
def get(request):
queryset = BuildingData.objects.all()
serializer = BuildingSerializer(queryset, many=True)
return Response(serializer.data)
class ReviewListAPI(APIView):
def get(request):
queryset = ReviewData.objects.all()
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
urls.py
from django.contrib import admin
from django.urls import path
from crawling_data.views import ReviewListAPI
from crawling_data.views import BuildingInfoAPI
urlpatterns = [
path('admin/', admin.site.urls),
path('api/buildingdata/', BuildingInfoAPI.as_view()),
path('api/buildingdata/<slug:slug>/', ReviewListAPI.as_view())
]
serializers.py
from rest_framework import serializers
from .models import ReviewData
from .models import BuildingData
class BuildingSerializer(serializers.ModelSerializer) :
class Meta :
model = BuildingData
fields = '__all__'
class ReviewSerializer(serializers.ModelSerializer) :
class Meta :
model = ReviewData
fields = '__all__'
models.py
from django.db import models
import uuid
# Create your models here.
from django.utils.text import slugify
def generate_unique_slug(klass, field):
origin_slug = slugify(field, allow_unicode=True)
unique_slug = origin_slug
numb = 1
while klass.objects.filter(slug=unique_slug).exists():
unique_slug = '%s-%d' % (origin_slug, numb)
numb += 1
return unique_slug
class BuildingData(models.Model):
building_name = models.CharField(max_length=50, unique=True)
slug = models.SlugField(max_length=50, unique=True, allow_unicode=True, default=uuid.uuid1)
building_loc = models.CharField(max_length=50)
building_call = models.CharField(max_length=20)
building_time = models.CharField(max_length=50)
def save(self, *args, **kwargs):
if self.slug: # edit
if slugify(self.building_name, allow_unicode=True) != self.slug:
self.slug = generate_unique_slug(BuildingData, self.building_name)
else: # create
self.slug = generate_unique_slug(BuildingData, self.building_name)
super(BuildingData, self).save(*args, **kwargs)
'''
def save(self, *args, **kwargs):
self.slug = slugify(self.building_name, allow_unicode=True)
try:
return super().save(*args, **kwargs)
except:
print(f"the repeated slug is: `{self.slug}`")
raise
'''
class ReviewData(models.Model):
#building = models.ForeignKey(BuildingData, related_name='reviews', on_delete=models.CASCADE, null=False, blank=False)
building_name = models.CharField(max_length=50)
review_content = models.TextField()
star_num = models.FloatField()
I think there's no problem with models.
But I can't find which makes get() error.
And I think error from(api/buildingdata/) prevents making slug url(api/buildingdata//) pages. (It says page not found when I enter slug url)
Is there any problem with my code?
add self parameter to your get method like this:def get(self,request) or just use generic views more clear and DRY.

Uploading Multiple Images django REST

I would like to upload multiple images using the Django model field(ImageField).
I created a model and was able to upload multiple images on the admin side like so https://imgur.com/BzVDPC5
I got the idea here (https://github.com/raszidzie/Multiple-Images-Django-Tutorial) in the Post(admin.py)
admin.py
from django.contrib import admin
from .models import School,SchoolImage
class SchoolImageAdmin(admin.StackedInline):
model = SchoolImage
#admin.register(School)
class SchoolAdmin(admin.ModelAdmin):
list_display=('school_name','school_type',"school_country")
search_fields=('school_name','school_type',"school_country")
list_filter=('school_name','school_type','school_gender')
inlines = [SchoolImageAdmin]
class Meta:
model =School
#admin.register(SchoolImage)
class SchoolImageAdmin(admin.ModelAdmin):
pass
I created the SchoolImage Model to handle multiple images in admin.py
models.py
from django.db import models
from django_countries.fields import CountryField
from partial_date import PartialDateField
class School(models.Model):
school_name = models.CharField(max_length = 30)
school_country = CountryField()
school_city = models.CharField(max_length= 30,default= None)
school_population = models.IntegerField()
school_description = models.TextField(max_length = 300)
year_build = PartialDateField()
total_branches = models.IntegerField()
school_fees = models.IntegerField()
school_images = models.FileField()
def __str__(self):
return self.school_name
class SchoolImage(models.Model):
schoolImages = models.ImageField()
school = models.ForeignKey(School, on_delete=models.CASCADE)
def __str__(self):
return self.school.school_name
not sure how to make it work in the veiws
here is my views code
from rest_framework.response import Response
from rest_framework.decorators import api_view
from rest_framework import status
from .models import School
from .serializers import *
#api_view(['GET','POST'])
def school_list(request):
if request.method == 'GET':
data = School.objects.all()
serializer = SchoolSerializer(data, context={'request': request},many = True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = SchoolSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response( status=status.HTTP_201_CREATED)
return Response(serializer.errors,status=status.HTTP_404_NOT_FOUND)
How do I make it work in my views??

How to get all related_name fields in django with serializers?

here is my models.py
from __future__ import unicode_literals
from django.db import models
class User(models.Model):
name = models.CharField(max_length=200)
company_name = models.ForeignKey('Company',on_delete=models.CASCADE)
def __str__(self):
return self.name
class Company(models.Model):
name = models.CharField(max_length=200)
phone_number = models.IntegerField(null=True,blank=True)
def __str__(self):
return self.name
class Catalog(models.Model):
name = models.CharField(max_length=200)
no_of_pcs = models.IntegerField(null=True,blank=True)
per_piece_price = models.DecimalField(null=True,blank=True,max_digits=10,decimal_places=2)
company_name = models.ForeignKey(Company,on_delete=models.CASCADE)
def __str__(self):
return self.name
here is my seralizers.py
from rest_framework import serializers
from .models import *
from django.db.models import Sum,Avg,Max,Min,Count,F,Q
class CatalogSerializer(serializers.HyperlinkedModelSerializer):
dynamic_data = serializers.SerializerMethodField()
class Meta:
model = Catalog
fields = '__all__'
def get_dynamic_data(self, obj):
totalpieces = Catalog.objects.all().aggregate(total_pieces=Count('no_of_pcs'))
totalprice = Catalog.objects.all().aggregate(total_price=Sum('per_piece_price'))
return totalprice,totalpieces
class CompanySerializer(serializers.ModelSerializer):
class Meta:
model = Company
fields = ('name', 'phone_number', 'catalog','user')
class UserSerializer(serializers.ModelSerializer):
name = serializers.StringRelatedField()
company_name = serializers.StringRelatedField()
class Meta:
model = User
fields = '__all__'
here is my view.py
from __future__ import unicode_literals
from django.http import HttpResponse
from .models import *
import json
from django.http import JsonResponse, HttpResponse
from .serializers import *
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from rest_framework import viewsets
class CatalogView(viewsets.ModelViewSet):
queryset = Catalog.objects.select_related('company_name')
serializer_class = CatalogSerializer
class CompanyView(viewsets.ModelViewSet):
queryset = Company.objects.all()
serializer_class = CompanySerializer
class UserView(viewsets.ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
here is my urls.py
from django.conf.urls import url, include
from django.contrib import admin
from api import views
from rest_framework.urlpatterns import format_suffix_patterns
from rest_framework import routers
router = routers.DefaultRouter()
router.register('catalogs',views.CatalogView)
router.register('companies',views.CompanyView)
router.register('users',views.UserView)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include(router.urls)),
]
when i will go
http://127.0.0.1:8000/companies/
m getting
[
{
"name": "google",
"phone_number": 12,
"catalog": [
5
]
}
]
m expecting this..
[
{
"url": "google",
"name": "google",
"phone_number": 123214214,
"catalog_details":[
"name": "sobhagya",
"no_of_pcs": 22,
"per_piece_price": "3567.00",
]
}
]
here I am able to get only id of related_name which i have set as foreignkKey but I expect all the fields like this above..
please check the json api formats
thanks,
class CompanySerializer(serializers.ModelSerializer):
catalog = CatalogSerializer(many=True) # if you want many catalog objects connected to the company else many=False
class Meta:
model = Company
fields = ('name', 'phone_number', 'catalog','user')
you need to call the catalog serializer inside of the company serializer to get the related objects

Categories