I am working of django rest framework api_root. It cannot find view even though I name it.
# board/urls.py
from django.urls import path
from rest_framework.urlpatterns import format_suffix_patterns
from .views import BoardList, BoardDetail, api_root
app_name = 'board'
urlpatterns = [
path('boards/', BoardList.as_view(), name='board-list'), # board-list
path('boards/<int:pk>', BoardDetail.as_view(), name='board-detail'),
path('', api_root),
]
urlpatterns = format_suffix_patterns(urlpatterns)
# board/views.py
from django.contrib.auth.models import User
from django.shortcuts import render
from rest_framework import generics, permissions, serializers
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse
from .models import Board
from .serializers import BoardSerializer
from .permissions import IsAuthorOrReadOnly
#api_view(['GET'])
def api_root(request, format=None):
return Response({
'boards': reverse('board-list', request=request, format=format) # board-list
})
class BoardList(generics.ListCreateAPIView):
queryset = Board.objects.all()
serializer_class = BoardSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
def perform_create(self, serializer):
serializer.save(author=self.request.user)
It throws error,
Reverse for 'board-list' not found. 'board-list' is not a valid view function or pattern name.
Why it cannot find view name?
Since you included an app_name in your urls.py, you need to specify the view name with the app name, so:
#api_view(['GET'])
def api_root(request, format=None):
return Response({
'boards': reverse('board:board-list', request=request, format=format) # board-list
})
Related
I have this REST API:
urlpatterns = [
path('admin/', admin.site.urls),
path('users/', UserViewSet.as_view({'get': 'list',
'post': 'create',
'delete': 'delete'})),
path('users/<uuid:pk>/video/', UserViewSet.as_view({'post': 'video'}))
]
How can i rewrite this with routers?
Default router with register method creates API -> GET users/ and POST users/ and also DELETE /users/{id} but it's different from current, because i need DELETE /users/ endpoint.
Or, maybe, in this situation it would be more correct to use my code with dictionaries?
assuming that UserViewSet is indeed a viewset, you can use the restframework's default router to register the router for /users/, and then add an action to handle you /video/ route from that viewset.
urls.py
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'users/', UserViewSet, basename='users')
urlpatterns = [
path('admin/', admin.site.urls),
]
urlpatterns += router.urls
viewsets.py
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import (
CreateModelMixin, RetrieveModelMixin,
DestroyModelMixin, ListModelMixin
)
from rest_framework.decorators import action
from rest_framework.parsers import MultiPartParser
class UserViewSet(CreateModelMixin, RetrieveModelMixin,
DestroyModelMixin, ListModelMixin, GenericViewSet):
# serializer class
# queryset
# permissions
#action(methods=['post'], parser_classes=(MultiPartParser,), detail=True)
def video(self, request, pk=None, *args, **kwargs):
# Implementation to upload a video
Edit
To create a bulk DELETE of users endpoint, I would create a Mixin class, as there is no django mixin for Deleting on the index of a router..
class BulkDeleteModelMixin:
def destroy(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
self.perform_destroy(queryset)
headers = self.get_success_headers(serializer.data)
return Response(serializer.data,
status=status.HTTP_201_CREATED, headers=headers)
def perform_destroy(self, queryset):
queryset.delete()
And inherit from this class in your viewset
viewsets.py
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import (CreateModelMixin, RetrieveModelMixin, ListModelMixin)
from some_app.mixins import BulkDeleteModelMixin
class UserViewSet(CreateModelMixin, RetrieveModelMixin,
BulkDeleteModelMixin, ListModelMixin, GenericViewSet):
I have a project that has React as it's frontend & Django as it's backend. after i integrated React with django it works perfectly but the paths i created in React with react-router-dom doesn't load when i search the page on my browser. meaning, i can load http://127.0.0.1:8000 comfortably but if i try to search http://127.0.0.1:8000/rooms/1/UCL a path that i created with React-router-dom using it's Link, it throws an error calling Page not found
how can i fix this ?
#my URL.py
from re import template
from xml.etree.ElementInclude import include
from django.contrib import admin
from django.urls import path,include
from django.views.generic import TemplateView
urlpatterns = [
path('admin/', admin.site.urls),
path('api/',include('api.urls')),
path('',TemplateView.as_view(template_name='index.html')),
]
my views.py
import profile
from rest_framework.response import Response
from django.http import HttpResponse
from rest_framework.decorators import api_view
from app.models import *
from .serializers import *
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
from rest_framework_simplejwt.views import TokenObtainPairView
#api_view(['GET','PUT'])
def updateRoomData(request,pk):
try:
message = Message.objects.get(id=pk)
except message.DoesNotExist:
return HttpResponse(status=404)
if request.method=='GET':
serializer = messageSerializer(message)
if request.method == 'PUT':
serializer = messageSerializer(message, data=request.data)
if serializer.is_valid():
serializer.save()
else:
return Response(serializer.errors, status=400)
return Response(serializer.data)
I am working on a photography website and i have created a rest api for blog but i am facing trouble how to display the api on template.
My project structure
enter image description here
This is my view.py of Blog
from rest_framework.response import Response
from rest_framework import permissions
from rest_framework.views import APIView
from rest_framework.generics import ListAPIView, RetrieveAPIView
from blog.models import BlogPost
from blog.serializers import BlogPostSerializer
from rest_framework.renderers import TemplateHTMLRenderer
class BlogPostListView(ListAPIView):
queryset = BlogPost.objects.order_by('-date_created')
serializer_class = BlogPostSerializer
lookup_field = 'slug'
permission_classes = (permissions.AllowAny, )
class BlogPostDetailView(RetrieveAPIView):
queryset = BlogPost.objects.order_by('-date_created')
serializer_class = BlogPostSerializer
lookup_field = 'slug'
permission_classes = (permissions.AllowAny, )
class BlogPostFeaturedView(ListAPIView):
queryset = BlogPost.objects.all().filter(featured=True)
serializer_class = BlogPostSerializer
lookup_field = 'slug'
permission_classes = (permissions.AllowAny, )
class BlogPostCategoryView(APIView):
serializer_class = BlogPostSerializer
permission_classes = (permissions.AllowAny, )
def post(self, request, format=None):
data = self.request.data
category = data['category']
queryset = BlogPost.objects.order_by('-date_created').filter(category__iexact=category)
serializer = BlogPostSerializer(queryset, many=True)
return Response(serializer.data)
This is urls.py of Blog
from django.urls import path
from .views import BlogPostListView, BlogPostDetailView, BlogPostFeaturedView, BlogPostCategoryView
urlpatterns = [
path('', BlogPostListView.as_view(), name='bl'),
path('featured', BlogPostFeaturedView.as_view()),
path('category', BlogPostCategoryView.as_view()),
path('<slug>', BlogPostDetailView.as_view()),
]
This urls.py of application
from django.contrib import admin
from django.urls import path, include
from django.views.generic import TemplateView
from portfolio import urls, views
from blog import urls
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name = 'index'),
path('portfolio/', include('portfolio.urls')),
path('gallery/', views.gallery, name = 'gallery'),
path('shop/', views.shop, name = 'shop'),
path('photo/<str:pk>', views.viewPhoto, name = 'photo'),
path('add/', views.addPhoto, name = 'add'),
path('api-auth/', include('rest_framework.urls')),
path('summernote/', include('django_summernote.urls')),
path('blog/', include('blog.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Rest api for Blog is working, how do use the rest api to display on blog.html??
enter image description here
views.py
from django.shortcuts import render
from rest_framework import viewsets
from django.http import HttpResponse
from .serializers import TodoSerializer
from .serializers import UserSerializer
from .models import Todo
from .models import User
class TodoView(viewsets.ModelViewSet):
serializer_class = TodoSerializer
queryset = Todo.objects.all()
def get_object(request):
return "Added";
class UserView(viewsets.ModelViewSet):
serializer_class = UserSerializer
queryset = User.objects.all()
def get_object(request):
print("request", request)
return "Registered";
class LoginView(viewsets.ModelViewSet):
#serializer_class = UserSerializer
#queryset = User.objects.all()
#print("queryset = ",queryset[len(queryset)-1].email_id)
#print("serializer_class = ",serializer_class)
def get_object(self,request):
return HttpResponse("request")
# Create your views here.
urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework import routers
from todo import views
router = routers.DefaultRouter()
router.register(r'users', views.UserView)
router.register(r'todos', views.TodoView)
router.register(r'login', views.LoginView)
print("In url file")
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
]
This is my views.py file and urls.py file.
I have a model created for user, with fields- email_id and password
CRUD operations are implemented automatically, so how do I validate data passed from the login form in frontend
Please tell me what's wrong in the code. I am not able to do the login part.
I am getting some issues with my urls. I don't have any 'account/' route but i when I want to visit 'login/' and after logging in it should redirect me to my profile... but it is taking me to this route: "http://127.0.0.1:8000/accounts/login/?next=/profile/"
I am sorry if I've posted any unnecessary kinds of stuff:
mainapp.urls
from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.urls import path, include
from forms.views import RegisterView,LoginView
from django.conf import settings
from django.conf.urls.static import static
from user_profile import views as profile_views
from blog import views
urlpatterns = [
path('admin/', admin.site.urls),
path('register/',RegisterView.as_view(), name='register'),
path('login/', LoginView.as_view(), name = 'login'),
path('profile/',profile_views.profile,name='profile'),
path('updateprofile/',profile_views.updateprofile,name='update_profile'),
path('',include('blog.urls')),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL,
document_root=settings.MEDIA_ROOT)
forms.views(Login/Logout)View
from django.shortcuts import render, redirect,reverse
from django.http import HttpResponse
from django.contrib.auth import authenticate, get_user_model, logout
from django.utils.http import is_safe_url
from django.contrib.auth.decorators import login_required
from django.views.generic import CreateView, FormView
from .models import User
from .forms import RegisterForm,LoginForm
class LoginView(FormView):
form_class = LoginForm #instance
template_name = 'forms/login.html'
success_url = '/profile/'
def User_logout(request):
if request.method == "POST":
logout(request)
return redirect(reverse('login'))
LoginForm:
class LoginForm(forms.Form):
email = forms.EmailField(label='email')
password = forms.CharField(widget=forms.PasswordInput)
def form_valid(self,form):
request=self.request
next_=request.GET.get('next')
next_post=request.POST.get('next')
redirect_path=next_ or next_post or None
email=form.cleaned_data.get('email')
password=form.cleaned_data.get('password')
user=authenticate(username=email, password=password)
if user is not None:
login(request, user)
try:
del request.session['UserProfile.html']
except:
pass
if is_safe_url(redirect_path, request.get_host()):
return redirect(redirect_path)
else:
return redirect("login")
return super(LoginView, self).form_invalid(form)
set a variable in your urls.py of you mainapp as following
appname='mainapp'
now in your login view add following
def get_success_url(self):
return reverse('mainapp:profile')
Currently, in Django 3.2, the reverse method is written this way:
def get_success_url(self):
return reverse('profile')
No need to add appname var in your urls.py