How to create view from External http request json and Internal Database using Django Rest Framework - django-rest-framework

I need to combine external json using request and Internal Database, But the condition is when someone call API we need to get empidlong from Model for call external API from specific URL, Then external API will return JSON and i need to merge this JSON with my json that create by Django REST API Framework
Here is my code
models.py :
from django.db import models
import requests
from django.core.files import File
from urllib import request
import os
# Create your models here.
class getData(models.Model):
company = models.CharField(max_length=150)
description = models.CharField(max_length=150)
period = models.CharField(max_length=150)
plate_no = models.CharField(max_length=150, primary_key=True)
project_code = models.CharField(max_length=150)
costcenter = models.CharField(max_length=150)
empidlong = models.CharField(max_length=150)
class Meta:
db_table = 'car_information'
serializers.py
from rest_framework import serializers
from .models import getData
class CarSerializer(serializers.ModelSerializer):
class Meta:
model = getData
fields = "__all__"
views.py
from django.shortcuts import render
from rest_framework import viewsets, filters
from .models import getData
from .serializers import CarSerializer
import requests
class CarViewSet(viewsets.ModelViewSet):
queryset = getData.objects.all()
serializer_class = CarSerializer
filter_backends = (filters.SearchFilter,)
#search_fields = ('plate_no')
__basic_fields = ('plate_no',)
search_fields = __basic_fields
serializer = CarSerializer(queryset, many=True)
data = serializer.data
for a in data:
empid= a['empidlong']
r = requests.get('http://192.168.10.32/Employees/'+empid)
def get_queryset(self):
queryset = getData.objects.all()
emp = self.request.query_params.get('emp', None)
if emp is not None:
queryset = queryset.filter(empidlong=emp)
return queryset
I have no idea how to do it. I stuck this for week.
Thank in advance.

Where are you expecting the json from? if from a user, you can access the json from the request. Then you can use it in your orm query. You CarViewSet seem to be doing way more than it should be. What is your goal exactly?

Related

Rename field in Serializer.data

I am currently implementing an API client for which I want to validate the request sent using serializers.
To do so, I create my serializer like this:
class TransactionRequestSerializer(serializers.Serializer):
counterparty = serializers.UUIDField(required=False)
from_datetime = serializers.DateTimeField(required=False, source='from')
to_datetime = serializers.DateTimeField(required=False, source='to')
transaction_type = serializers.CharField(required=False, source='type')
Issue is that source doesn't fit my usage, because when I do serializer.data, I get:
{'from_datetime': '2020-07-07T16:08:00.313236+02:00'}
Instead of
{'from': '2020-07-07T16:08:00.313236+02:00'}
Those data are then passed as params for my request, like requests.get('', params=params)
Of course, I cannot name the field "from" as it is reserved. Any idea about how can I get "from" in my serializer.data?
I tink this has already been answered.
Please take a look at this question: How to change field name in Django REST Framework
I think the same solution will work for you.
I think it's not possible, so I switched to Serializer.validated_data instead so I can use source.
this example as same the question :
model:
from django.db import models
class ReceiveCallbackUrl(models.Model):
From = models.CharField(max_length=14)
to = models.CharField(max_length=14)
message = models.CharField(max_length=255)
messageid = models.IntegerField()
serializer:
from rest_framework.serializers import ModelSerializer,SerializerMethodField
from .models import ReceiveCallbackUrl
class ReceiveCallbackUrlModelSerializer(ModelSerializer):
From = SerializerMethodField('from')
class Meta:
model = ReceiveCallbackUrl
fields = ['From', 'to', 'message', 'messageid']
view:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .serializer import ReceiveCallbackUrlModelSerializer
class ReceiveCallbackUrlAPIView(APIView):
def post(self, request):
serializer = ReceiveCallbackUrlModelSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(request.POST, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_406_NOT_ACCEPTABLE)

Record exists or not in DB? Django Api generic Views

I want to write a class based API view to check if the record exists in DB or not then return True else False by using rest_framework. How could I create CBV to check it? Please help me with this context.
here is my serializer class
class EmployeeSerializer(ModelSerializer):
class Meta:
model = Employee
fields = '__all__'
here is my url
path('employee/<name>/<code>/',views.EmployeeExist.as_view(),name = 'employee_exits')
Here is how you can create simple view:
from rest_framework import status, response
from rest_framework import generics
class EmployeeExistView(generics.GenericAPIView):
serializer_class = None
def get(self, request, *args, **kwargs):
employee = Employee.objects.filter(id=kwargs.get('id'))
if employee.exists():
return response.Response(status=status.HTTP_200_OK)
return response.Response(status=status.HTTP_404_NOT_FOUND)

How to update records in a Postgres table with Django rest framework

I have basic django app that returns data from Postgres tables in an AWS RDS instance.
I have a few endpoint which relate to few tables in the RDS.
What I want to do is update records in table. If the record exists it should be updated, if it does not exist then nothing should happen Orit should throw an error.
This is my models.py file -
from django.db import models
class Campaigns(models.Model):
id_campaign = models.CharField(max_length=250, blank=True, null=True)
status = models.CharField(max_length=250, blank=True, null=True)
id_taste_cluster = models.CharField(max_length=250, blank=True, null=True)
I want to update the status field in this table where status = ' '.
This is my serialiser file -
from rest_framework import serializers
from .models import Campaigns
class Campaigns_1_Serializer(serializers.ModelSerializer):
class Meta:
model = Campaigns
fields = ('id_campaign', 'status', 'id_taste_cluster')
This is my views file -
from rest_framework import viewsets
from rest_framework.response import Response
from rest_framework import generics
from .models import Campaigns
from .serializers import Campaigns_1_Serializer
class UpdateView(viewsets.ModelViewSet):
def update(self, request, *args, **kwargs):
data = request.DATA
queryset = Campaigns.objects.filter(status='')
serializer = Campaigns_1_Serializer(queryset, data=data, many=True)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
I want to give the users the option to update only those campaigns for which the status is ' '(blank).
How can I do that ?
You need to change your update method :
#your imports
from rest_framework import serializers
class YourModelViewset(ModelViewSet):
#your code
def update(self, request, *args, **kwargs):
instance = self.get_object()
# checks if the object staus is empty
If object.status == "" or object.status is None :
raise serializers.ValidationError("your error message")
return super(YourModelViewset, self).update(request, *args, **kwargs)

User specific Serializers in Django Rest Framework

I am creating Serializers in my DRF and so far it's working good the problem is that it is showing data of all the users
serializers.py
from rest_framework import serializers
from .models import Quiz
class TodoSerializer(serializers.ModelSerializer):
class Meta:
model = Quiz
fields = ('foo', 'bar')
How do I make my Serializers User Specific such that it only returns the data of the user who is using the app?
Views.py
class TodoView(viewsets.ModelViewSet):
serializer_class = TodoSerializer
queryset = Quiz.objects.all()
User specific filtering has nothing to do with serializers. Serializers are used to convert complex python objects to/from native python datatypes that can be rendered in JSON/XML etc. It is convenient to do your filtering in your view. Here is an example by using mixins:
# views.py
from .models import Quiz
from .serializers import TodoSerializer
from rest_framework import mixins, viewsets
from rest_framework.response import Response
class TodoListViewSet(viewsets.GenericViewSet, mixins.ListModelMixin):
queryset = models.Quiz.objects.all()
serializer_class = TodoSerializer
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
# filter your todos here
queryset = queryset.filter(user=request.user)
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)

django rest framework many to many serialize and apiview

I am creating APIView for book list and add, delete.
Is this serialization the right way?
I want to show a list of books, but I do not know what to put in '?'.
member/models.py
class MyUser(AbstractBaseUser, PermissionsMixin):
username = models.EmailField(unique=True, max_length=256)
nickname = models.CharField(max_length=256)
is_staff = models.BooleanField(default=False)
created_date = models.DateTimeField(auto_now_add=True)
mybook = models.ManyToManyField(Book)
book/models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=256)
author = models.CharField(max_length=200)
def __str__(self):
return self.title
book/seralizers.py
from rest_framework import serializers
from book.models import Book
class MyBookSerializer(serializers.ModelSerializer):
mybook = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
class Meta:
model = Book
fields = (
'title',
'author',
)
apiview.py
class MyBook(APIView):
def get(self, request):
mybook = Book.objects.filter(myuser=?)
serializer = MyBookSerializer(mybook)
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request):
pass
def delete(self, request):
pass
If you want create a CRUD for model, depends on a request.user you can simply use ModelViewSet:
from rest_framework import viewsets
class MyBookViewSet(viewsets.ModelViewSet):
serializer_class = MyBookSerializer
def get_queryset(self, request):
return Book.objects.filter(myuser=self.request.user)
That's all for view. You only need to specify router for a viewset.
urls.py:
from rest_framework import routers
router = routers.DefaultRouter()
router.register('books', MyBookViewSet)
urlpatterns = []
urlpatterns += router.urls
Include this usl file in a root urls and you are done.
You also need to specify related_name for m2m field if you want to use myuser name:
mybook = models.ManyToManyField(Book, related_name='myuser')
And you don't need this field in a serializer:
mybook = serializers.PrimaryKeyRelatedField(many=True, read_only=True)
viewsets docs
routers docs

Resources