How do I filtered a generic object from model ,store it like Radis and Return a unique string(key) against this object using django - django-rest-framework

I'm beginner in Django.I get stuck from last 3 days by doing this task.I have try on google, Youtube but unfortunately failed to complete.Actually, I want to design a Api in which I filter data against title from jobs model that is in working.but the problem is that I want to first filter data from jobs model then store it against a unique id(string that is xyz) in storage, storage could be any like Redis or database and also return the same string(xyz) in response Api.Id will be use later on for result Api.
Please, help me I shall be very thankful to you
#My Jobs view
View.py
from rest_framework import viewsets, mixins
from .models import Job
from .serializers import JobSerializer
from rest_framework import filters,fields, serializers
from rest_framework import filters
class JobViewSet(
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.ListModelMixin,
viewsets.GenericViewSet,
):
"""
Updates and retrieves user accounts
"""
queryset = Job.objects.all()I want
serializer_class = JobSerializer
filter_backends = [filters.SearchFilter]
search_fields = ['title']

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)

DRF - in filter, use field-value instead of default pk / id

I'm trying to use DRF's filters so that the URL query is like so:
/roadname/?road=M5
not like so
/roadinfo/?road=1
I can't seem to do it when I've got a ForeignKey relationship.
I've tried using lookup_field with no luck (although not sure how this would work for multiple filter fields anyway - I don't think that's the answer). I've tried using a get_queryset() method in views as in the second example in the documentation. A comment I came across suggested that this is bad RESTApi practice - is it? How would a user know to type in '1' to get results for 'M5' in a front-end client?
I've set up two really simple models (and serializers, views, etc.) to try these out as below.
If I use RoadName, I have to type the name into the filter search box (rather than having a dropdown), but the url query is how I want it.
If I use RoadInfo (which has a ForeignField to RoadName), I get a drop down in the filter box, but the url query uses the ForeignKey pk.
My question: How can I set it so that when I use RoadInfo, the query uses the field value rather than the id/pk?
Models
from django.db import models
class RoadName(models.Model):
road = models.CharField(max_length=50)
def __str__(self):
return str(self.road)
class RoadInfo(models.Model):
road = models.ForeignKey(RoadName, on_delete='CASCADE')
# other data
def __str__(self):
return str(self.road)
Serializers
from traffic.models import *
from rest_framework import serializers
class RoadNameSerializer(serializers.ModelSerializer):
road = serializers.CharField()
class Meta:
model = RoadName
exclude = ('id',)
class RoadInfoSerializer(serializers.ModelSerializer):
road = RoadNameSerializer()
class Meta:
model = RoadInfo
exclude = ('id',)
Views
from traffic.serializers import *
from traffic.models import *
from django_filters import rest_framework as filters
from rest_framework import viewsets
class RoadNameViewSet(viewsets.ReadOnlyModelViewSet):
""" List of all traffic count Counts """
queryset = RoadName.objects.all()
serializer_class = RoadNameSerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_fields = '__all__'
class RoadInfoViewSet(viewsets.ReadOnlyModelViewSet):
""" List of all traffic count Counts """
queryset = RoadInfo.objects.all()
serializer_class = RoadInfoSerializer
filter_backends = (filters.DjangoFilterBackend,)
filterset_fields = '__all__'
The data M5 on the road attribute of RoadName model. It can be filtered by road__road from RoadInfo model.
So, Try /roadname/?road__road=M5

How to create view from External http request json and Internal Database using 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?

Django 1.11.15 and query string parameters

I am trying to query from django i.e http://localhost:8000/search/Tesco/apples to get a query of json list, the one below.
[
{
"id": 12,
"Date": "2018-08-02",
"Title": "Rosedene Farms Small Sweet Apple 520G",
"Price": 0.96,
"PricePerWeight": "1.85/kg",
"FinalOffer": "undefined undefined",
"ProductID": 292249576
},
My urls.py:
from django.conf.urls import url, include
from . import views
from rest_framework import routers
router = routers.DefaultRouter()
router.register('Tesco', views.TescoView)
urlpatterns = [
url('', include(router.urls), name='search'),
url(r'^search/', include(router.urls), name='searchTwo')
my views.py
from __future__ import unicode_literals
from django.shortcuts import render
from rest_framework import viewsets
from .models import Tesco
from .serializers import TescoSerializers
from django.core.urlresolvers import reverse_lazy, reverse
class TescoView(viewsets.ModelViewSet):
queryset = Tesco.objects.filter(Title__icontains='apple')
serializer_class = TescoSerializers
how would I get the URL http://localhost:8000/search/tesco/ to query through the database for the list of json?
I don't think searching like:
http://localhost:8000/search/Tesco/apples
is a normal pattern in Django Rest Framework (DRF), so I think you're going to hit a lot of resistance trying to make this pattern work with DRF. If I may suggest, I believe you're in the X-Y Problem space - "That is, you are trying to solve problem X, and you think solution Y would work, but instead of asking about X when you run into trouble, you ask about Y."
Normally, filtering parameters are specified on the listing view of the model. For your model, your complete Tesco instance listing can be found at:
http://localhost:8000/Tesco/
If you want to filter this down, you append query parameters after a ? like:
http://localhost:8000/Tesco/?title__icontains=apple
or
http://localhost:8000/Tesco/?ProductID=292249576
or multiple searching filters like:
http://localhost:8000/Tesco/?ProductID=292249576&title__icontains=apple
To use this pattern, you need to modify your viewset and add a FilterSet. This is what your views.py file would look like:
from __future__ import unicode_literals
from django.shortcuts import render
from rest_framework import viewsets
from .models import Tesco
from .serializers import TescoSerializers
from django.core.urlresolvers import reverse_lazy, reverse
# Import filtering libraries
import django_filters
from rest_framework import filters
class TescoFilterSet(django_filter.FilterSet):
title__icontains = django_filter.Filter('Title', lookup_expr='icontains')
class Meta:
model = Tesco
fields = ('title__icontains', 'ProductID')
class TescoView(viewsets.ModelViewSet):
queryset = Tesco.objects.filter(Title__icontains='apple')
serializer_class = TescoSerializers
# Hook up filterset
filter_backends = (django_filters.rest_framework.DjangoFilterBackend, filters.OrderingFilter,)
filter_class = TescoFilterSet
# allow ordering on any field
ordering_fields = '__all__'
In my experience the nginx and apache webservers seem to work well with this pattern when you get to content caching.
For more on filtering, see the DRF guide on Filtering.
Ordering
Per your comment, you can order by specifying order_fields as seen above. Then you can add the ordering parameter.
vvvvvvvvvvvvvv
http://localhost:8000/Tesco/?title__icontains=apple&ordering=price
This will be ascending price.
Add a - before price and the order is reversed or descending:
http://localhost:8000/Tesco/?title__icontains=apple&ordering=-price
^

restframework-jwt how can I handle payload?

I used Django restframework to implement api server.
Also I used djangorestframework-jwt for token authentication.
[urls.py]
from django.contrib import admin
from django.urls import path, include
from rest_framework_jwt.views import refresh_jwt_token
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('rest_auth.urls')),
path('registration/', include('rest_auth.registration.urls')),
path('refresh-token/', refresh_jwt_token),
]
Everything works fine. But I want to know that How can I extract payload from token?
For example, There is article table.
[/article/serializers.py]
from rest_framework import serializers
from . import models
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = models.Article
fields = '__all__'
[models.py]
from django.db import models
class Article(models.Model):
subject = models.CharField(max_length=20)
content = models.CharField(max_length=100)
[views.py]
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from . import models, serializers
class Article(APIView):
def get(self, request, format=None):
all_article = models.Article.objects.all()
serializer = serializers.ArticleSerializer(all_article, many=True)
return Response(data=serializer.data, status=status.HTTP_200_OK)
In this case, I want to return correct response only payload['userid'] == article's userid.
How can I extract username from jwt token?
Previous, I just use jwt not djangorestframework-jwt, So just decode request data and use it.
But now I use djangorestframework-jwt, I confused How can I do it.
Is there any solution about this?
Thanks.
I solved this issue after checking the library's documentation here
https://jpadilla.github.io/django-rest-framework-jwt/
I needed to Override all the functions to return custom response as required in my application.
Also any additional settings we need to specify in JWT_AUTH in settings.py of my application.
i.e.
JWT_AUTH = {
'JWT_RESPONSE_PAYLOAD_HANDLER':
'myapp.utils.jwt_response_payload_handler',
}
And needed to define jwt_response_payload_handler function in a util folder in my app to override the default function.

Resources