Django: Model Queryset to Pandas to Django Rest Framework - django

I am trying to accomplish the following workflow in my Django project:
Query my database
Convert the returned queryset to a pandas dataframe in order to perform some calculations & filtering
Pass the final dataframe to Django REST API Framework
if I understand correctly, I have to use django-pandas for Step 2. and Django REST Pandas for Step 3.
I installed both and read the documentaton, but I have no clue how to make it work.
What I have achieved to far is to set up my model, views, serializes and urls to have the original queryset rendered via the Django Rest Framework.
If anyone could give me a hint on how to integrate pandas in this workflow, it would be highly appreciated.
my models.py file
from django.db import models
class Fund(models.Model):
name = models.CharField(max_length=100)
commitment_size = models.IntegerField(blank=True, null=True)
commitment_date = models.DateField(blank=True, null=True)
def __str__(self):
return self.name
my views.py file
from rest_framework import generics
from rest_framework.views import APIView
from pages.models import Fund
from .serializers import FundSerializer
class FundAPIView(generics.ListAPIView):
queryset = Fund.objects.all()
serializer_class = FundSerializer
my serializers.oy file
from rest_framework import serializers
from pages.models import Fund
class FundSerializer(serializers.ModelSerializer):
class Meta:
model = Fund
fields = ('name', 'commitment_size', 'commitment_date')

So i figured it out. First, you need to install django-pandas and django rest framework (but no need to install django REST pandas)
models.py and serializers.py files stay the same as above, but the views file is different
from rest_framework.views import APIView
from rest_framework.response import Response
from django_pandas.io import read_frame # Import django_pandas.io read frame
from pages.models import Fund
from .serializers import FundSerializer
class TestData(APIView):
authentication_classes = []
permission_classes = []
def get(self, request, format=None):
data = Fund.objects.all() # Perform database query
df = read_frame(data) # Transform queryset into pandas dataframe
df['testcolumn'] = "testdata" # Perform some Pandas Operation with dataframe
return Response(df) # Return the result in JSON via Django REST Framework

Related

Save external kraken API json in my Django database?

The context
I want to save json data from an external public kraken API in my Django database
Do you have any suggestion of (i) how can i get the json response working accordingly, and (ii) how can i afterwards save it in my django database?
If you have any ideas or tips I would be very grateful.
Thank you!
My view.py
from rest_framework import generics
from .serializers import KrakenSerializer
from kraken.models import Kraken
import requests
class KrakenList(generics.RetrieveAPIView):
serializer_class = KrakenSerializer
queryset = Kraken.objects.all()
def get_object(self):
url = 'https://api.kraken.com/0/public/Time'
r = requests.get(url, headers={'Content-Type':
'application/json'})
kraken = r.json()
return kraken
def seed_kraken():
for i in kraken:
krakenss = Kraken(
unixtime=i["unixtime"],
)
krakenss.save()
My urls.py
from .views import KrakenList
from django.urls import path
app_name = 'kraken'
urlpatterns = [
path('', KrakenList.as_view(), name='listkraken'),
]
My serializers.py
from rest_framework import serializers
from kraken.models import Kraken
class KrakenSerializer(serializers.ModelSerializer):
class Meta:
model = Kraken
fields = ('unixtime',)
My models.py
from django.db import models
class Kraken(models.Model):
unixtime = models.IntegerField(default=0)
This the Django REST framework with wrong empty json answer:
This is how the json unixtime answer should look like in my Django REST framework
The issue
Do you have any suggestion of (i) how can i get the json info working accordingly, and (ii) how can i afterwards save it in my django database?

Make Django 3 REST render HTML template

I am trying to build a Django (version 3.05) REST API call that will render to a chosen HTML template.
I am, however, receiving a number of errors that I haven't found a solution to on StackOverflow (And yes, I've looked far and wide).
Since my errors are many and varying depending on what I attempt, let me rather ask how to do it correctly to begin with.
In my view set up (below), what do I need to add (or change) in order to render the queryset to an HTML template?
models.py:
from django.db import models
class Hero(models.Model):
name = models.CharField(max_length=60)
alias = models.CharField(max_length=60)
def __str__(self):
return self.name
serializers.py:
from rest_framework import serializers
from .models import Hero
class HeroSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Hero
fields = ('name', 'alias')
views.py:
from rest_framework import viewsets
from .serializers import HeroSerializer
from .models import Hero
class HeroViewSet(viewsets.ModelViewSet):
queryset = Hero.objects.all().order_by('name')
serializer_class = HeroSerializer
# over here - how do I render the queryset /to/my/template.html
myapi/urls.py:
from django.urls import include, path
from rest_framework import routers
from . import views
router = routers.DefaultRouter()
router.register(r'heroes', views.HeroViewSet)
you should change your view from ModelViewSet to APIView.
with API view you can include renderer_classes and template_name.
check here for more information

How to accept form data and return it along with the results of some processing in Django RESTFramework?

I am trying to understand Django RESTFramework. I am already familiar with Django. I want to create an endpoint that accepts some text data and processes it and returns it to the user along with the results of the processing (in text). I have completed a couple of tutorials on the topic but I still don't understand how it works. Here is an example from a working tutorial project. How can I edit it to achieve my goal? It all looks automagical.
# views.py
from rest_framework import generics
from .models import Snippet
from .serializers import SnippetSerializer
class SnippetList(generics.ListCreateAPIView):
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
​
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
# Here I would like to accept form data and process it before returning it along with the
# results of the processing.
queryset = Snippet.objects.all()
serializer_class = SnippetSerializer
Okay, I think you are a newbie in Django rest and try to understand its flow so I can explain it with an example of a subscription plan.
First, create a model in models.py file
from django.db import models
class SubscriptionPlan(models.Model):
plan_name = models.CharField(max_length=255)
monthly_price = models.IntegerField()
yearly_price = models.IntegerField()
Then create views in a view.py file like
from rest_framework.views import APIView
class SubscriptionCreateAPIView(APIView):
serializer_class = SubscriptionSerializer
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(
{'message': 'Subscription plan created successfully.',
'data': serializer.data},
status=status.HTTP_201_CREATED
)
and then define a serializer for validation and fields in which we can verify which fields will be included in the request and response object.
serializers.py
from rest_framework import serializers
from .models import SubscriptionPlan
class SubscriptionSerializer(serializers.ModelSerializer):
plan_name = serializers.CharField(max_length=255)
monthly_price = serializers.IntegerField(required=True)
yearly_price = serializers.IntegerField(required=True)
class Meta:
model = SubscriptionPlan
fields = (
'plan_name', 'monthly_price', 'yearly_price',
)
def create(self, validated_data):
return SubscriptionPlan.objects.create(**validated_data)
Now add urls in src/subsciption_module/urls.py
from django.urls import path
from .views import SubscriptionCreateAPIView
app_name = 'subscription_plan'
urlpatterns = [
path('subscription_plan/', SubscriptionCreateAPIView.as_view()),
]
At the end include module url in root urls.py file where your main urls will be located. It will be the same directory which contains settings.py and wsgi.py files.
src/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include('src.subscription_plan.urls', namespace='subscription_plan')),
]
That's it. This is how flow works in django rest and you can process data and display data in this way. For more details you can refer django rest docs.
But this is not in any way different from what you do with plain Django. Your SnippetDetail view is just a class-based view, and like any class-based view if you want to do anything specific you override the relevant method. In your case, you probably want to override update() to do your custom logic when receiving a PUT request to update data.

Set some views which use Django Rest Framework API

I have a very basic Django Rest API.
I don't know how to have some HTML views, in the same django project, which uses API (finally keeping API returning JSON only).
I followed this, but it seems to change the API View (in this case, curl will retrieve HTML and not JSON) :
https://www.django-rest-framework.org/api-guide/renderers/#templatehtmlrenderer
Do I need another Django App ? Another Django project ? Some JS ?
EDIT :
Ok, I've seen it's possible, thanks to rrebase.
But I can't retrieve the JSON with Curl, here my views.py
from rest_framework import generics
from rest_framework.renderers import TemplateHTMLRenderer, JSONRenderer
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework.permissions import IsAdminUser
from . import models
from . import serializers
class UserListView(generics.ListAPIView):
renderer_classes = [JSONRenderer, TemplateHTMLRenderer]
template_name = 'profile_list.html'
def get(self, request):
queryset = models.CustomUser.objects.all()
serializer_class = serializers.UserSerializer
return Response({'profiles': queryset})
My models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
def __str__(self):
return self.email
I get an error "Object of type 'CustomUser' is not JSON serializable" when I request the API (http://127.0.0.1:8000/api/v1/users/)
Sorry, it's some different that initial question...
Yes, you can have both. The link you provided to docs has the following:
You can use TemplateHTMLRenderer either to return regular HTML pages using REST framework, or to return both HTML and API responses from a single endpoint.
When making an API request, set the ACCEPT request-header accordingly to html or json.
Finally I made some conditions in my view, and it's working
class UserListView(generics.ListAPIView):
renderer_classes = [JSONRenderer, TemplateHTMLRenderer]
permission_classes = (IsAdminUser,)
def get(self, request):
queryset = CustomUser.objects.all()
if request.accepted_renderer.format == 'html':
data = {'profiles': queryset}
return Response(data, template_name='profile_list.html')
else:
serializer = UserSerializer(queryset, many=True)
data = serializer.data
return Response(data)

'<' not supported between instances of 'Applicant' and 'Applicant'

I have a model that I want to use for predictions which I have loaded using pickle and I have a form created in using django. But when a user submits the form I want it to be in store it in a csv format in a variable so I can perform Xgboost prediction on every form the user fills and after it outputs the prediction. COuld it be its not getting any input. New to this
from django.db import models
from django import forms
from django.core.validators import MaxValueValidator, MinValueValidator
# Create your models here.
type_loan=(("Cash loan","Cash loan"),
("Revolving loan","Revolving Loan"))
Gender=(("Male","Male"),
("Female","Female"))
Yes_NO=(("YES","YES"),("NO","NO"))
status=(("Single","Single"),
("Married","Married"),
("Widow","Widow"),
("Seprated","Divorce"))
Highest_Education=(("Secondary","Secondary"),
("Incomplete Higher","Incomplete Higher"),
("Lower Secondary","Lower Secondary"),
("Academic Degree","Academic Degree"))
Income_type=(("Working","Working Class"),
("State Servant","Civil Servant"),
("Commercial Associate","Commercial Associate"),
("Pensioner","Pensioner"),
("Student","Student"),
("Businessman","Business Owner"))
class Applicant(models.Model):
name=models.CharField(default="Jon Samuel",max_length=50,null="True")
Birth_date=models.DateField(default="2018-03-12",blank=False, null=True)
Status=models.CharField(choices=status,max_length=50)
Children=models.IntegerField(default=0,validators=[MinValueValidator(0),MaxValueValidator(17)])
Highest_Education=models.CharField(choices=Highest_Education,max_length=50)
Gender=models.CharField(choices=Gender, max_length=50)
loan_type=models.CharField(choices=type_loan, max_length=50)
own_a_car=models.CharField(choices=Yes_NO,max_length=50)
own_a_house=models.CharField(choices=Yes_NO,max_length=50)
def __str__(self):
return self.name
views.py
from django.shortcuts import render
from .models import Applicant
from .forms import Applicant_form
from django.views.generic import ListView, CreateView, UpdateView
from django.core.cache import cache
import xgboost as xgb
import pickle
from sklearn.preprocessing import LabelEncoder
class CreateMyModelView(CreateView):
model = Applicant
form_class = Applicant_form
template_name = 'loan/index.html'
success_url = '/loan/results'
context_object_name = 'name'
class MyModelListView(ListView):
template_name = 'loan/result.html'
context_object_name = 'Results'
def get_queryset(self):
queryset=Applicant.objects.all()
with open('model/newloan_model','rb') as f:
clf=pickle.load(f)
le=LabelEncoder()
le.fit(queryset)
queryset=le.transform(queryset)
d_test = xgb.DMatrix(queryset)
predict=clf.predict(d_test)
return (predict)
One way to accomplish this is to use a Django package called django-import-export. This way you can export every object inside a model to a csv file.
https://django-import-export.readthedocs.io/en/latest/