i am new to DRF, and implemneting class based views and a sample example is this i have tried
#api_view(['GET', 'POST'])
class ProductList(APIView):
print "inside"
def get_user_products(self, request, user_id, format=None):
products = Product.objects.all(user_id=user_id)
serializer = ProductSerializer(products, many=True)
return Response(serializer.data)
def get_seller_products(self, request, seller_id, format=None):
products = Product.objects.filter(seller_id=seller_id)
serializer = ProductSerializer(products, many=True)
return Response(serializer.data)
def post(self, request, user_id, seller_id, format=None):
serializer = ProductSerializer(data=request.DATA, context={'request':request})
if serializer.is_valid():
serializer.object.user = User.objects.get(id=user_id)
serializer.object.seller = Seller.objects.get(id=seller_id)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
i this class for my product apis , but i am not sure how can i access individual methods to access the corresponding result, like how can i hit get_user_products or get_seller_products
Right now when i call this api like this http://localhost:8000/products
as GET method this class executed and it prints "inside" as you can see, but how do i call the methods inside it
Here is the url.py for this app
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^login$', 'userapp.views.login_user', name="login"),
url(r'^products$', 'productapp.views.ProductList', name="product-list"),
]
You're not supposed to use the api_view decorator to decorate class-based views; you use api_view with function-based views.
If you want to use a class-based view, like the one in your example, remove the print statement, and the api_view decorator, and include the view in your urlconf by importing the view, and using ProductList.as_view(), as shown in the tutorial. In your case, the urlconf might look like this:
from productapp.views import ProductList
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^login$', 'userapp.views.login_user', name="login"),
url(r'^products$', ProductList.as_view(), name="product-list"),
]
Also, keep in mind, that using strings containing import paths for your views in urlpatterns is deprecated, and support for this will be removed in an upcoming version of Django. Instead, import all your views inside your urlconf, and use the view functions directly, for example:
from productapp.views import ProductList
from userapp.views import login_user
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
url(r'^login$', login_user, name="login"),
url(r'^products$', ProductList.as_view(), name="product-list"),
]
Related
views.py
from django.views.generic import ListView
from .models import Staff
class StaffListView(ListView):
model = Staff
template_name = 'staff/staff_list.html'
def get_queryset(self):
return Staff.objects.filter(websites__path=self.kwargs['web'])
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('<str:web>/staff/', include('staff.urls')),
# I want to set web=chemical, if url is http://127.0.0.1:8000/staff
]
With Django URL you cannot do that. But I have a cheat way. You can use middlewares > Check the URL if this one is a URL validated with empty param > redirect it to the correct URL.
Sample:
def redirect_middleware(get_response):
def middleware(request, *args, **kwargs):
# In here I write a sample with a basic check, you can use regex to check.
if request.path == "/staff":
return redirect('/chemical/staff')
response = get_response(request, *args, **kwargs)
return response
return middleware
A simple solution is to use RedirectView ?
urlpatterns = [
path('admin/', admin.site.urls),
path('<str:web>/staff/', include('staff.urls')),
path('staff', StaffRedirectView.as_view()),
]
# in views
from django.views.generic.base import RedirectView
class StaffRedirectView(RedirectView):
def get_redirect_url(self, *args, **kwargs):
return "/chemical" + self.request.get_full_path()
I think, this idea can be work for your case
urlpatterns = [
path('admin/', admin.site.urls),
path('staff/', include('staff.urls'),kwargs={'web':''}),
path('<str:web>/staff/', include('staff.urls')),
]
staff.urls.py
urlpatterns = [
path('',views.StaffListView.as_view())
]
I created an endpoint and registered it in urls.py. When I try to hit the endpoint I get a 404 error but on the 404 page the url is shown as one of the patterns django tried to match. Stumped.
api.py
class UpdateLast(viewsets.GenericViewSet, UpdateModelMixin):
def get(self):
return XYZModel.objects.all()
def partial_update(self, request, *args, **kwargs):
if request.user.is_superuser:
with transaction.atomic():
for key, value in request.data:
if key == 'tic':
XYZModel.objects.filter(ticker=request.data['tic']).filter(trail=True).update(
last_high=Case(
When(
LessThan(F('last_high'),
request.data['high']),
then=Value(request.data['high'])),
default=F('last_high')
)
)
urls.py (this is inside the app)
router = routers.DefaultRouter()
router.register('api/dsetting', DViewSet, 'dsetting')
router.register('api/update-last-high', UpdateLast, 'update-last-high')
urlpatterns = [
path('', include(router.urls))
]
urls.py (main)
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('my_app.urls')),
When I hit the end-point api/update-last-high I get a 404 page.
On that page the exact end-point is shown as a pattern that django tried to match.
^api/update-last-high/(?P[^/.]+)/$ [name='update-last-high-detail']
^api/update-last-high/(?P[^/.]+).(?P[a-z0-9]+)/?$ [name='update-last-high-detail']
from rest_framework import routers
from . import views
from django.urls import path, include
router = routers.DefaultRouter()
router.register('api/dsetting', DViewSet, 'dsetting')
router.register('api/update-last-high', UpdateLast, 'update-last-high')
# you forgot to include the router.urls
urlpatterns = [
path('', include(router.urls))
]
I'm trying to add a secondary admin site and it's working correctly except that any links are pointing to the main admin site. Not sure how to get around this.
If I visit /dispatch/admin/ the model Run is visible but when I click the link it directs me to /admin/dispatch/run/ instead of /dispatch/admin/dispatch/run/.
Django==3.2.7
class DispatchAdminSite(admin.AdminSite):
pass
class DispatchRunAdmin(RunAdmin):
def get_queryset(self, request):
return (
super().get_queryset(request)
.filter_today_or_future()
)
def get_readonly_fields(self, request, obj=None):
return [f.name for f in self.model._meta.fields]
dispatch_admin_site = DispatchAdminSite(name='Dispatch')
dispatch_admin_site.register(models.Run, DispatchRunAdmin)
dispatch/urls.py
app_name = 'dispatch'
urlpatterns = [
path('admin/', admin.dispatch_admin_site.urls),
]
project/urls.py
urlpatterns = [
path('dispatch/', include('dispatch.urls')),
path('admin/', admin.site.urls),
]
For whatever reason the custom admin can't be added using include it has to be a top level URL in your project.
# project/urls.py
from django.contrib import admin
from dispatch.admin import dispatch_admin_site
urlpatterns = [
path('dispatch-admin/', dispatch_admin_site.urls),
path('admin/', admin.site.urls),
]
Trying to get the correct url path mapped back to my view in Django 2. Everytime I try i get a "not found" path.
views.py
class LoginView(APIView):
authentication_classes = ()
permission_classes = ()
#staticmethod
def post(request):
"""
Get user data and API token
"""
user = get_object_or_404(User, email=request.data.get('email'))
user = authenticate(username=user.email, password=request.data.get('password'))
if user:
serializer = UserSerializerLogin(user)
return Response(serializer.data)
return Response(status=status.HTTP_400_BAD_REQUEST)
main urls.py (snippet)
urlpatterns = [
path('', include('apiV1.v1.accounts.urls')),
path('admin/', admin.site.urls),
]
child urls.py
urlpatterns = [
path('login', LoginView.as_view(), name='login'),
]
I'm getting this error:
The included urlconf 'unsitiodigital.urls' does not appear to have any patterns in it.
The traceback points to this line
class Contacto(FormView):
template_name = "contacto.html"
form_class = FormContacto
success_url = reverse("main:mensaje_enviado") -->This Line
def form_valid(self, form):
form.send_email()
return super(Contacto, self).form_valid(form)
There are valid patterns, it works without the reverse line.
urls.py - general
urlpatterns = [
url(r'^', include('main.urls', namespace="main")),
url(r'^admin/', include(admin.site.urls)),
]
urls.py - main
from django.conf.urls import url
from main import views
urlpatterns = [
url(r'^$', views.Inicio.as_view(), name='inicio'),
url(r'^quienes_somos/$', views.QuienesSomos.as_view(), name='quienes_somos'),
url(r'^opciones/$', views.Opciones.as_view(), name='opciones'),
url(r'^contacto/$', views.Contacto.as_view(), name='contacto'),
-> url(r'^mensaje_enviado/$', views.MensajeEnviado.as_view(), name='mensaje_enviado')
]
So, ¿which is the correct user of reverse?. Thanks a lot.
The include path must be wrong
url(r'^', include('main.urls', namespace="main")), # the 'main.urls' path must be wrong
There are some ways you can include other urls. Try to import the patterns from the main.url module instead
from main.urls import urlpatterns as main_urls
url(r'^', include(main_urls, namespace="main"),
You also have to use reverse_lazy in the success_url.
from django.core.urlresolvers import reverse_lazy
class Contacto(FormView):
template_name = "contacto.html"
form_class = FormContacto
success_url = reverse_lazy("main:mensaje_enviado")
It is useful for when you need to use a URL reversal before your project’s URLConf is loaded.