How can i define default value for urls parameters in Django? - django

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())
]

Related

url is showing in page not found error in django?

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))
]

Django secondary admin site links to main admin site

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),
]

Django is not showing the right path when clicking on a link

This is what it shows when you click on the link
Page not found (404)
Request Method: GET Request URL:
http://localhost:8000/jobapplication/new/1
Using the URLconf defined in careal.urls, Django tried these URL
patterns, in this order:
^$ [name='landing-index']
^admin/
^accounts/
^taskmanager/
^login/$ [name='login']
The problem is that I don't know why it is opening the link as http://localhost:8000/jobapplication/new/1, when it should be http://localhost:8000/taskmanager/jobapplication/new/1
This is what I have in the urls.py
from django.conf.urls import include, url
from django.contrib import admin
from django.conf import settings
from django.contrib.auth import views as auth_views
from landingpage import views as landingpage_views
urlpatterns = [
url(r'^$', landingpage_views.index, name='landing-index'),
url(r'^admin/', admin.site.urls),
url(r'^accounts/', include('allauth.urls')),
url(r'^taskmanager/', include('taskmanager.urls')),
url(r'^login/$', auth_views.login, name='login'),
]
This is in urls.py in the app taskmanager
from django.conf.urls import url
from . import views
from taskmanager.views import *
app_name = 'taskmanager'
urlpatterns = [
# Task manager urls
url(r'^$', JobApplicationIndex.as_view(), name='index'),
url(r'jobapplication/add/(?P<jobpost_id>[0-9]+)/$', JobApplicationCreate.as_view(), name='jobapplication-add'),
url(r'jobapplication/new/(?P<jobpost_id>[0-9]+)/$', views.JobApplicationAdd, name='jobapplication-new'),
url(r'jobapplication/edit/(?P<jobpost_id>[0-9]+)/$', views.JobApplicationEdit, name='jobapplication-edit'),
url(r'jobapplication/edit/(?P<pk>[0-9]+)/$', JobApplicationUpdate.as_view(), name='jobapplication-edit'),
url(r'^jobapplication/(?P<pk>[0-9]+)/$', JobApplicationDetails.as_view(), name='jobapplication-detail'),
# Company urls
url(r'company/$', CompanyIndex.as_view(), name='company-index'),
url(r'company/add/$', CompanyCreate.as_view(), name='company-add'),
url(r'^company/(?P<pk>[0-9]+)/$', CompanyDetails.as_view(), name='company-detail'),
# Job Post urls
url(r'jobpost/$', JobPostIndex.as_view(), name='jobpost-index'),
url(r'^jobpost/(?P<pk>[0-9]+)/$', JobPostDetails.as_view(), name='jobpost-detail'),
# Statistics urls
url(r'^kpi/$', views.kpi, name='kpi'),
]
And this is what I have in views.py in taskmanager, related to jobapplication
# Job Application views
class JobApplicationIndex(generic.ListView):
template_name = 'taskmanager/jobapplication_index.html'
def get_queryset(self):
if self.request.user.is_authenticated:
return JobApplication.objects.filter(user=self.request.user.id).order_by('-created_at')
class JobApplicationCreate(CreateView):
model = JobApplication
fields = ['jobpost', 'sent_date', 'deadline', 'success_rate']
def get_initial(self):
jobpost = get_object_or_404(JobPost, id=self.kwargs.get('jobpost_id'))
return {
'jobpost':jobpost,
}
def form_valid(self, form):
form.instance.user = self.request.user
return super(JobApplicationCreate, self).form_valid(form)
class JobApplicationDetails(generic.DetailView):
model = JobApplication
class JobApplicationEdit(UpdateView):
model = JobApplication
#fields = ['jobpostid', 'is_favorite']
#p = JobApplication.objects.get(id=jobpostid)
#p.is_favorite = is_favorite
#p.save()
class JobApplicationUpdate(UpdateView):
model = JobApplication
fields = ['sent_date', 'deadline', 'success_rate']
template_name_suffix = '_update_form'
def JobApplicationAdd(request, jobpost_id):
if request.method == 'GET' and request.user.is_authenticated:
# If job app for this id exists, redirect to that job app page with a message
if JobApplication.objects.filter(jobpost_id=int(jobpost_id)).exists():
existing = JobApplication.objects.get(jobpost_id=int(jobpost_id))
messages.add_message(request, messages.INFO, 'An application for this opening already exists.')
return HttpResponseRedirect(reverse('taskmanager:jobapplication-detail', args=[existing.id]))
jobapp = JobApplication(user=request.user, jobpost_id=int(jobpost_id), success_rate=50)
jobapp.save()
return HttpResponseRedirect(reverse('taskmanager:index'))
--- The thing is all the other links in taskmanager work and when you click on them, the right path is opened Eg: -
- http://localhost:8000/taskmanager/jobpost/
- http://localhost:8000/taskmanager/jobpost/2/
- http://localhost:8000/taskmanager/company/2/
- http://localhost:8000/taskmanager/kpi/
Try Adding an uptick in front of the regex patterns like you did for the ones that are working.
from django.conf.urls import url
from . import views
from taskmanager.views import *
app_name = 'taskmanager'
urlpatterns = [
# Task manager urls
url(r'^$', JobApplicationIndex.as_view(), name='index'),
url(r'^jobapplication/add/(?P<jobpost_id>[0-9]+)/$', JobApplicationCreate.as_view(), name='jobapplication-add'),
url(r'^jobapplication/new/(?P<jobpost_id>[0-9]+)/$', views.JobApplicationAdd, name='jobapplication-new'),
url(r'^jobapplication/edit/(?P<jobpost_id>[0-9]+)/$', views.JobApplicationEdit, name='jobapplication-edit'),
url(r'^jobapplication/edit/(?P<pk>[0-9]+)/$', JobApplicationUpdate.as_view(), name='jobapplication-edit'),
url(r'^jobapplication/(?P<pk>[0-9]+)/$', JobApplicationDetails.as_view(), name='jobapplication-detail'),
# Company urls
url(r'^company/$', CompanyIndex.as_view(), name='company-index'),
url(r'^company/add/$', CompanyCreate.as_view(), name='company-add'),
url(r'^company/(?P<pk>[0-9]+)/$', CompanyDetails.as_view(), name='company-detail'),
# Job Post urls
url(r'^jobpost/$', JobPostIndex.as_view(), name='jobpost-index'),
url(r'^jobpost/(?P<pk>[0-9]+)/$', JobPostDetails.as_view(), name='jobpost-detail'),
# Statistics urls
url(r'^kpi/$', views.kpi, name='kpi'),
]

Call specific method in Class based api view django

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"),
]

django reverse with namespace

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.