How to fix "ImproperlyConfigured" erros in django rest_framework urls.py - python-3.x

I am trying to figure out how django rest framework works and write some code. But i am getting
django.core.exceptions.ImproperlyConfigured: The included URLconf 'tutorial.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import
what is circular import? I can't understand. I created a app called quickstart inside i create serializers.py file.
quickstart/serializers.py
from django.contrib.auth.models import User, Group
from rest_framework import serializers
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = User
fields = ('url', 'username', 'email', 'groups')
class GroupSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Group
fields = ('url', 'name')
quickstart/views.py
from django.contrib.auth.models import User, Group
from rest_framework import viewsets
from quickstart.serializers import UserSerializer, GroupSerializer
class UserViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all().order_by('-date_joined')
serializer_class = UserSerializer
class GroupViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows groups to be viewed or edited.
"""
queryset = Group.objects.all()
serializer_class = GroupSerializer
quickstar/urls.py
from rest_framework import routers
from .views import UserViewSet, GroupViewSet
router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'groups', views.GroupViewSet)
urlpatterns = router.urls
testing/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('', include('quickstart.urls')),
# path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
path('admin/', admin.site.urls),
]
can you please describe why this error happened frequently?
Thank you!

Related

Why is when i do put request using Django rest framework I got 200 but when i try to see one of fields it shows null using get request not the put one

I was trying to do put request on Postman and it's successful, but when I try the get method to get same result one of the fields which is car_year shows null.
from django.shortcuts import render
from django.http import HttpResponse,JsonResponse
from rest_framework.parsers import JSONParser
from .models import Driver
from .serializers import DriverSerializer
from django.views.decorators.csrf import csrf_exempt
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from rest_framework import generics
from rest_framework import mixins
from rest_framework.views import APIView
# Create your views here.
class GenericAPIView(generics.GenericAPIView,mixins.ListModelMixin,mixins.CreateModelMixin,mixins.UpdateModelMixin,mixins.RetrieveModelMixin,mixins.DestroyModelMixin):
serializer_class = DriverSerializer
queryset = Driver.objects.all()
lookup_field = 'id'
def get(self,request,id=None):
if id:
return self.retrieve(request)
else:
return self.list(request)
def post(self,request):
return self.create(request)
def put(self,request,id=None):
return self.update(request,id)
from django.db import models
# Create your models here.
class Driver(models.Model):
name=models.CharField(max_length=100)
email=models.EmailField(max_length=100)
phone_number=models.IntegerField(max_length=None)
car_model=models.CharField(max_length=100)
car_year=models.IntegerField(max_length=None)
def __str__(self):
return self.name
from rest_framework import serializers
from .models import Driver
class DriverSerializer(serializers.ModelSerializer):
class Meta:
model=Driver
fields=['id','name','email','phone_number','car_model','car_year'] ```
Instead of using that very GenericAPIView class that you've made, look into using a ModelViewSet. Besides that, you are missing the permissions_classes in your APIView.
Try this:
from rest_framework import viewsets, permissions
class DriverViewSet(viewsets.ModelViewSet):
queryset = Driver.objects.all()
serializer_class = DriverSerializer
permission_classes = [permissions.IsAuthenticated]
Also, your serializer looks fine.
car_year and phone_number are IntegerFields and you've set the max_length on them. That max_length=None should be removed.
Try the things I mentioned and it should would fine. I'm guessing it's most likely the view you are using but it could also be the integer field.
Also, if this is going to be a production app, the phone_number field shouldn't be an integer but rather a string, or better yet, you can use the django-phonenumber-field library.

Querying users based on time

I want to add a class-based view to return users created from one date to another date. I have tried the following are there other ways to filter the user-created between two dates?
While doing this I get:
TypeError: get() missing 1 required positional argument: 'to_date'
views.py
class RegisteredUserFilter(APIView):
serializer = RegisteredUserFilterSerializer
def get(self, from_date, to_date):
userondate = User.objects.filter(created_at__range=[from_date, to_date]).values()
return Response({"User": userondate})
serializers.py
class RegisteredUserFilterSerializer(serializers.Serializer):
from_date = serializers.DateField()
to_date = serializers.DateField()
model = User
full code at: https://github.com/abinashkarki/rest_framework_authentication/tree/master/authapp
using Django filters
serilaizers.py
add the following
class RegisteredUserFilterSerializer(serializers.Serializer):
class Meta:
model = User
fields = ['username', 'created_at']
make file name it filters.py in same path of views.py
filters.py
from django_filters.rest_framework import FilterSet
import django_filters
from .models import User
from django_filters.widgets import RangeWidget
class UserFilter(FilterSet):
date_range = django_filters.DateFromToRangeFilter(label='Date Range', field_name='created_at',
widget=RangeWidget(attrs={'type': 'date'}))
class Meta:
model = User
fields = ['created_at']
Views.py
from .serializers import RegisteredUserFilterSerializer
from .filters import UserFilter
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.generics import ListAPIView
class RegisteredUserFilter(ListAPIView):
serializer_class = RegisteredUserFilterSerializer
filter_backends = [DjangoFilterBackend]
filterset_class = UserFilter
model = User
urls.py add
from django.urls import path
from .views import RegisteredUserFilter
urlpatterns = [
path('users-filter/', RegisteredUserFilter.as_view(), name="user-filter"),
]
finally do not forget to make
pip install django-filter
and add it to installed app in settings.py
INSTALLED_APPS = [
...
'django_filters',
]
for more information refer to https://django-filter.readthedocs.io/en/stable/guide/rest_framework.html
another approach
you can make this process manually by overriding the get method and getting query parameters manually
and return response after serializing the query set

Django REST Framework API : How to save/upload images with the name given by user(e.g. username.jpg) at Django server

I want to upload image with the name (which is given by user) at Django server through rest API,but i am not be able to find out the solution for this.Please tell me how to upload image with given name.
here is my code(mainly):
IN API TASK ->URLS:
from django.conf.urls import include, url
from django.contrib import admin
from rest_framework import routers
from django.conf import settings
from myapi import views
from django.conf.urls.static import static
#Define API Routes
router = routers.DefaultRouter()
router.register(r'myimage', views.myimageViewSet) #we have only on viewset
urlpatterns = [
url(r'^',include(router.urls)),
url(r'^admin/',admin.site.urls),
]+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
IN My API
1. MODEL
from django.db import models
# Create your models here.
class myimage(models.Model):
my_name=models.CharField(max_length=50)
my_image=models.ImageField(upload_to='Images/',default='Images/None/No-img.jpg')
def __str__(self):
return self.my_name
2.SERIALIZERS
from rest_framework import serializers
from .models import myimage
class myimageserializer(serializers.ModelSerializer):
class Meta:
model =myimage
fields=('id','my_name','my_image')
3. VIEWS
from django.shortcuts import render
from .models import myimage
from rest_framework import viewsets
from .serializers import myimageserializer
from rest_framework import filters
import django_filters.rest_framework
class myimageViewSet(viewsets.ModelViewSet):
queryset = myimage.objects.all() #We use Filters for Ordering so remove order_by part
serializer_class = myimageserializer
filter_backends = (django_filters.rest_framework.DjangoFilterBackend,filters.OrderingFilter,)
ordering = ('id','my_name',)
4.ADMIN
from django.contrib import admin
from .models import myimage
admin.site.register(myimage)
You need to use FileParser to be able to get your image details in the request data object. I recommend you to follow the example in DRF's FileParser Example
I changed my code as mentioned below and now its working for me if you have any better solution please suggest here #happycoding
1. views.py
from django.shortcuts import render
from .models import myimage
from rest_framework import views
from .serializers import myimageserializer
import django_filters.rest_framework
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
class myimageView(APIView):
def get(self, request):
myimagelocal= myimage.objects.all()
serializer = myimageserializer(myimagelocal, many=True)
return Response(serializer.data)
def post(self, request):
myname=request.data['my_image'].name
myformat=""
for c in reversed(myname):
myformat+=c
if c=='.' :
break
myformat=myformat[: : -1]
request.FILES['my_image'].name=request.data['my_name']+myformat
serializer = myimageserializer(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)
IN API_TASK->URLS:
from django.conf import settings
from django.conf.urls.static import static
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls,name='admin'),
path('',include('myapi.urls'))
]+static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
IN API_Task->myapi->url
from django.urls import path
from .views import myimagedetailsView, myimageView
urlpatterns = [
path('myimage/', myimageView.as_view(),name='myimageView'),
]
Rest files unchanged

Exception Type: AssertionError Exception Value: Class RatingSerializers missing "Meta.model" attribute

hi guys i a newbie and learning django-framework and building rest-api
i'm stuck at this error . Its gives me error at venv\lib\site-packages\rest_framework\serializers.py in get_fields, line 1020. and says Class RatingSerializers missing "Meta.model" attribute.
i did all migration and makemigration
Exception Type: AssertionError
Exception Value:
Class RatingSerializers missing "Meta.model" attribute
urls.py
from django.contrib import admin
from django.urls import path
from rest_framework import routers
from django.conf.urls import include
from .views import MovieViewSet, RatingViewSet
router = routers.DefaultRouter()
router.register('movies', MovieViewSet)
router.register('ratings', RatingViewSet)
urlpatterns = [
path('', include(router.urls)),
]
models.py
from django.db import models
from django.contrib.auth.models import User
from django.core.validators import MaxValueValidator, MinValueValidator
class Movie(models.Model):
title = models.CharField(max_length=32)
description = models.TextField(max_length=500)
class Rating(models.Model):
movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
stars = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(5)])
class Meta:
unique_together = (('user', 'movie'),)
index_together = (('user', 'movie'),)
serializer.py
from rest_framework import serializers
from .models import Movie, Rating
class MovieSerializers(serializers.ModelSerializer):
class Meta:
model: Movie
fields = ('id', 'title', 'description')
class RatingSerializers(serializers.ModelSerializer):
class Meta:
model: Rating
fields = ('id', 'stars', 'user', 'movie')
views.py
from django.shortcuts import render
from rest_framework import viewsets
from .models import Movie, Rating
from .serializers import MovieSerializers, RatingSerializers
class MovieViewSet(viewsets.ModelViewSet):
queryset = Movie.objects.all()
serializer_class = MovieSerializers
class RatingViewSet(viewsets.ModelViewSet):
queryset = Rating.objects.all()
serializer_class = RatingSerializers
i have no idea what is wrong with it.
You have to do
model = Rating
instead of
model: Rating
And same for the movies serializer too

How to change the default search query parameter in URL in Django REST framework?

In Django REST Framework. By default it uses - /?search= in URL while searching for anything.
For Example http://127.0.0.1:8000/api/branches/?search=RTGS
And this url successfully getting the result.
But I need to change the URL to http://127.0.0.1:8000/api/branches/autocomplete?q=RTGS
In the documentation, https://www.django-rest-framework.org/api-guide/settings/#search_param
It is given that it is set by default. https://www.django-rest-framework.org/api-guide/settings/#search_paramd we can change.
I am wondering how.
Thanks
https://www.django-rest-framework.org/api-guide/settings/#search_param
urls.py
from django.urls import path, include
from . import views
from rest_framework import routers
router = routers.DefaultRouter()
# router.register('bank', views.BankView)
router.register('branches/autocomplete', views.BankDetailView)
# router.register('branches/list', views.BankAPIListView)
urlpatterns = [
path('api/', include(router.urls)),
]
views.py
from django.shortcuts import render, redirect
from rest_framework import viewsets
from .models import Branches
from .serializers import BranchesSerializer
from rest_framework import filters
from rest_framework.filters import OrderingFilter
from rest_framework.pagination import PageNumberPagination
# from django_filters.rest_framework import DjangoFilterBackend
class BankDetailView(viewsets.ModelViewSet):
queryset = Branches.objects.all()
serializer_class = BranchesSerializer
filter_backends = [filters.SearchFilter, OrderingFilter]
# Partial Search with the field in branch
search_fields = ['^branch']
# Ordering Filter field by ifsc in ascending order
# filter_backends = [DjangoFilterBackend]
# filterset_fields = ['ifsc']
serializers.py
from rest_framework import serializers
from .models import Branches
class BranchesSerializer(serializers.HyperlinkedModelSerializer):
class Meta :
model = Branches
fields = ['url' ,'ifsc', 'bank_id', 'branch', 'address', 'city',
'district', 'state']
http://127.0.0.1:8000/api/branches/autocomplete?q=RTGS&limit=3&offset=0
From the docs:
By default, the search parameter is named 'search', but this may be overridden with the SEARCH_PARAM setting.
Thus, in your settings.py:
REST_FRAMEWORK = {
'SEARCH_PARAM': 'q'
}
EDIT:
Here you can see the actual code:
Settings: https://github.com/encode/django-rest-framework/blob/master/rest_framework/settings.py#L68
Filters: https://github.com/encode/django-rest-framework/blob/master/rest_framework/filters.py#L42
If you'd like to change query parameter key in only one view, you can extend SearchFilter and then add it to filter_backends of your view.
class CustomSearchFilter(SearchFilter):
search_param = "q"
class MyListView(ListAPIView):
# ...
filter_backends = [CustomSearchFilter]
# ...

Resources