REST API Django does not show all tables in different endpoints - python

I am learning REST API Django and would appreciate your patience and help in understaing the below case.
in myproject/abcapp/forms.py
from django import forms
from .models import *
class ProfileForm(forms.ModelForm):
class Meta:
model=Profile
fields = "__all__"
class Zoo_data_2020Form(forms.ModelForm):
class Meta:
model=Zoo_data_2020
fields = "__all__"
in myproject/abcapp/models.py
from django.conf import settings
from django.db import models
class ProfileQuerySet(models.QuerySet):
pass
class ProfileManager(models.Manager):
def get_queryset(self):
return ProfileQuerySet(self.model,using=self._db)
class Profile(models.Model):
name=models.CharField(settings.AUTH_USER_MODEL,max_length=200)
subtype=models.CharField(max_length=500)
type=models.CharField(max_length=500)
gender=models.CharField(max_length=500)
objects = ProfileManager()
class Meta:
verbose_name = 'Profile'
verbose_name_plural = 'Profiles'
managed = False
db_table ='profiles'
def __str__(self):
return '{}'.format(self.name)
class Zoo_data_2020QuerySet(models.QuerySet):
pass
class Zoo_data_2020Manager(models.Manager):
def get_queryset(self):
return Zoo_data_2020QuerySet(self.model,using=self._db)
class Zoo_data_2020(models.Model):
name=models.CharField(max_length=200)
size=models.DecimalField(decimal_places=3,max_digits=100000000)
weight=models.DecimalField(decimal_places=3,max_digits=100000000)
age=models.DecimalField(decimal_places=3,max_digits=100000000)
objects = Zoo_data_2020Manager()
class Meta:
verbose_name = 'zoo_data_2020'
verbose_name_plural = 'zoo_data_2020s'
managed = False
db_table ='zoo_data_2020'
def __str__(self):
return '{}'.format(self.name)
in myproject/abcapp/api/views.py:
from rest_framework import generics, mixins, permissions
from rest_framework.views import APIView
from rest_framework.response import Response
import json
from django.shortcuts import get_object_or_404
from abcapp.models import *
from .serializers import *
def is_json(json_data):
try:
real_json = json.loads(json_data)
is_valid = True
except ValueError:
is_valid = False
return is_valid
class ProfileDetailAPIView(generics.RetrieveAPIView):
permission_classes = []
authentication_classes = []
queryset= Profile.objects.all()
serializer_class = ProfileSerializer
lookup_field = 'id'
class ProfileAPIView(generics.ListAPIView):
permission_classes = []
authentication_classes= []
serializer_class = ProfileSerializer
passed_id = None
search_fields = ('id','name','animal')
queryset = Profile.objects.all()
def get_queryset(self):
qs = Profile.objects.all()
query = self.request.GET.get('q')
if query is not None:
qs=qs.filter(name__icontains=query)
return qs
class Zoo_data_2020DetailAPIView(generics.RetrieveAPIView):
permission_classes = []
authentication_classes = []
queryset= Zoo_data_2020.objects.all()
serializer_class = Zoo_data_2020Serializer
lookup_field = ('id','name')
class Zoo_data_2020APIView(generics.ListAPIView):
permission_classes =[]
authentication_classes= []
serializer_class = Zoo_data_2020Serializer
passed_id = None
search_fields = ('id','name')
queryset = Zoo_data_2020.objects.all()
def get_queryset(self):
qs = Zoo_data_2020.objects.all()
query = self.request.GET.get('q')
if query is not None:
qs=qs.filter(name__icontains=query)
return qs
in myproject/abcapp/api/serializers.py:
from rest_framework import serializers
from abcapp.models import *
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model=Profile
fields = "__all__"
read_only_fields = ['name']
class Zoo_data_2020Serializer(serializers.ModelSerializer):
class Meta:
model = Zoo_data_2020
fields = "__all__"
read_only_fields = ['name']
in myproject/abcapp/api/urls.py:
from django.urls import path
from .views import *
urlpatterns = [
path('', ProfileAPIView.as_view()),
path('<id>/', ProfileDetailAPIView.as_view()),
path('', Zoo_data_2020APIView.as_view()),
path('<id>/', Zoo_data_2020DetailAPIView.as_view()),]
in myproject/urls.py:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/profile/', include('abcapp.api.urls')),
path('api/zoodata2020/', include('abcapp.api.urls')),
]
So when i do call http://127.0.0.1:8000/api/profile/ i get data from tables Profile, but when i do call http://127.0.0.1:8000/api/zoodata2020/ i get data again from table Profile not Zoo_data_2020. But when i remove from myproject/abcapp/api/urls.py:
path('', ProfileAPIView.as_view()),
path('<id>/', ProfileDetailAPIView.as_view()),
then it shows me data from table Zoo_data_2020 but then i can't get data from table Profile
how to fix it ? I am sure that i am doing smth wrong in urls.py in both app and the project. So what i need to do to make endpoints seperate ? and also how to show them both?
I want to call http://127.0.0.1:8000/api/profile/?search=TIGER and as result to give me information from both tables profiles and zoo_data_2020 as they contain different data but about the same 'name' which is TIGER. But currently when for example i call http://127.0.0.1:8000/api/profile/?search=TIGER it just shows me data from tabel Profile not from Zoo_data_2020
Please help to understand it and how to fix it. Thanks in advance.

In the project urls.py, you don't have to refer the same app multiple times, you can do that in the app's urls.py
Give this a try
myproject/urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('cfs.api.urls')),
]
myproject/abcapp/api/urls.py:
urlpatterns = [
path('profile', ProfileAPIView.as_view()),
path('profile/<id>/', ProfileDetailAPIView.as_view()),
path('zoo_data', Zoo_data_2020APIView.as_view()),
path('zoo_data/<id>/', Zoo_data_2020DetailAPIView.as_view()),
]

Related

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

type object 'PizzaMenu' has no attribute '_default_manager'

I have following error while i try to reach PizzaDetailView on template: AttributeError at /pizza/6/
type object 'PizzaMenu' has no attribute '_default_manager'.
Where is the problem?
models.py
class PizzaMenu(models.Model):
name = models.CharField(max_length=30)
description = models.TextField()
ingredients = models.CharField(max_length=100)
price = models.DecimalField(max_digits=4, decimal_places=2)
def __str__(self):
return self.name
class Meta:
ordering = ["price"]
views.py
from django.views.generic import TemplateView, ListView, DetailView
from .models import PizzaMenu
class IndexView(TemplateView):
template_name = "index.html"
class PizzaMenu(ListView):
model = PizzaMenu
template_name = "menu.html"
context_object_name = "pizza_menu"
# ordering = ["price"]
class PizzaDetailView(DetailView):
model = PizzaMenu
template_name = "pizza_detail.html"
context_object_name = "pizza_detail"
class About(TemplateView):
template_name = "about.html"
urls.py
from pizza.views import IndexView, PizzaMenu, About, PizzaDetailView
urlpatterns = [
path("", IndexView.as_view(), name="home"),
path("menu/", PizzaMenu.as_view(), name="menu"),
path("about/", About.as_view(), name="about"),
path("pizza/<int:pk>/", PizzaDetailView.as_view(), name="pizza_detail"),
path("admin/", admin.site.urls),
]
Don't name your view PizzaMenu, it will override the reference to the PizzaMenu for the other views. Usually class-based views have a …View suffix, so:
class IndexView(TemplateView):
template_name = 'index.html'
# add a View suffix to prevent collissions with the PizzaMenu model class
class PizzaMenuListView(ListView):
model = PizzaMenu
template_name = 'menu.html'
context_object_name = 'pizza_menu'
class PizzaDetailView(DetailView):
model = PizzaMenu
template_name = 'pizza_detail.html'
context_object_name = 'pizza_detail'
class AboutView(TemplateView):
template_name = 'about.html'

How to return all the message between two Users - Django/Python/Chat Building

I'm building a simple chat with Django-Rest-Framework in Python.
I created a GET/POST methods for Users and Chat.
MODEL
from django.db import models
from django.db.models.base import Model
class User(models.Model):
class Meta:
db_table = 'user'
user_firstname = models.CharField(max_length=200)
user_lastname = models.CharField(max_length=200)
class Chat(models.Model):
class Meta:
db_table = 'chat'
from_message = models.ForeignKey(User, on_delete=models.CASCADE, related_name='+')
message = models.CharField(max_length=1000)
to_message = models.ForeignKey(User, on_delete=models.CASCADE, related_name='+')
SERIALIZERS
from rest_framework import serializers
from .models import User, Chat
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = '__all__'
class ChatSerializer(serializers.ModelSerializer):
class Meta:
model = Chat
fields = '__all__'
URLS
from django.urls.conf import re_path
from . import views
urlpatterns = [
re_path(r'^users/$', views.UserList.as_view(), name='users-list'),
re_path(r'^chat/$', views.ChatList.as_view(), name='chat-get-list'),
re_path(r'^chat/(?P<from_id>.+)&(?P<to_id>.+)/$', views.ChatList.as_view(), name='chat-list'),
]
VIEWS
from rest_framework import generics, serializers
from .models import User, Chat
from .serializers import ChatSerializer, UserSerializer
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def get_queryset(self):
queryset = User.objects.all()
return queryset
class ChatList(generics.ListCreateAPIView):
queryset = Chat.objects.all()
serializer_class = ChatSerializer
def get_queryset(self):
queryset = Chat.objects.all()
from_id = self.request.query_params.get('from_id')
to_id = self.request.query_params.get('to_id')
if from_id is not None and to_id is not None:
queryset = Chat.objects.filter(from_message=from_id,to_message=to_id)
#Probably my error is here, because I'm specifying the messages. I need to add something like 'to_message=to_id or from_id
return queryset
THE PROBLEM:
When I send a message, I informed a from_id, to_id and a message itself, for example:
{
"from_id":1,
"message":"I'm sending a message to you",
"to_id":2
},
{
"from_id":2,
"message":"I'm replying your message",
"to_id":1
}
But when I'm trying to get all the messages between two persons, I get just what was send from_id to to_id, but I also need to return what was replyed, in that example the message "I'm replying your message".
I know that my problem is probably in the filter, but I don't know how to build in another way.
In that case, how to return all the messages between two Users?
To resolve that problem just add at views:
queryset1 = Chat.objects.filter(from_id=from_id,to_id=to_id)
queryset2 = Chat.objects.filter(from_id=to_id,to_id=from_id)
queryset = queryset1.union(queryset2)

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

django rest framework error while post through json data

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.

Categories