In the following code how will i know there are two hyper links which are pointing to the same view.My question is in view how will i know which link the user is referring to? how can i get the referred url context in the view
JS:
window.location = "/project/server/fserver";
window.location = "/project/server/";
urls:
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^fserver/$', views.IndexView.as_view(), name='index'),
views
class IndexView(tables.DataTableView, VolumeTableMixIn):
table_class = project_tables.VolumesTable
template_name = 'project/server/index.html'
def get_data(self):
print "In get data==============="
.......
https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.path
def get_data(self):
print self.request.path
...you could also do this with a single url pattern
url(r'^(?:fserver/)?$', views.IndexView.as_view(), name='index'),
or capturing as a kwarg passed to the view:
url(r'^((?P<page>fserver)/)?$', views.IndexView.as_view(), name='index'),
An Alternate way is:
-> Add a class variable in you view to store the url name:
class IndexView(tables.DataTableView, VolumeTableMixIn):
view_url_name = 'index'
........
-> Change the URL definition to following:
url(r'^$', views.IndexView.as_view(), name='index'),
url(r'^fserver/$', views.IndexView.as_view(view_url_name='index_fserver'), name='index_fserver'),
Also, this will help you get the url in more django-ish manner e.g. reverse(view_url_name)
Note: Two different urls should never be of the same name, as this creates ambiguity & After all the first matching name will be picked by Django so its of no use either.
Related
while practicing on Django I have faced the following problem of Identical URL Pattern. I have tried but fail to solve.
My project has one apps and the models are
class Category(models.Model):
title = models.CharField(max_length=150)
slug = models.SlugField(unique=True,blank=True, max_length=255)
class Post(models.Model):
title = models.CharField(max_length=200)
cats = models.ForeignKey(Category, on_delete=models.CASCADE)
slug = models.SlugField(unique=True,blank=True, max_length=255)
My urls.py
from django.contrib import admin
from django.urls import path
from post import views as apps
urlpatterns = [
path('admin/', admin.site.urls),
path('<slug:slug>/', apps.categoryView, name='category'),
path('<slug:slug>/',apps.PostView, name='calc_detail'),
]
Problem:
When I Put '/' in the second line of the urlpattern for Category View, category View works but post View doesn't work (404).
If remove '/' urlpattern for CategoryView , then post view Works but Category Views shows 404.
How should I configure these urls. I am using function based views
There's really no way to handle these except using different patterns or handling both in the same view, I would suggest different patterns:
from django.contrib import admin
from django.urls import path
from post import views as apps
urlpatterns = [
path('admin/', admin.site.urls),
path('pattern1/<slug:slug>/', apps.categoryView, name='category'),
path('pattern2/<slug:slug>/',apps.PostView, name='calc_detail'),
]
Also have you thought what would happen if a post and a category ended up having the same slug? Best to have different patterns.
About putting '/' making some url work and not it is because django appends slashes by default to each url, so if you really want to do this (NOT RECOMMENDED) you may set APPEND_SLASH = False in your setting and have one url with a slash and other without.
I am trying to filter products either by brand or category but the url path will only execute path('<slug:brand_slug>/', views.product_list,name='product_list_by_brand'), since it appears first and would not execute the second.
Is there a way I can probably merge both paths or cause both paths to work independently without taking order into consideration.
from . import views
app_name = 'shop'
urlpatterns = [
path('', views.product_list, name='product_list'),
path('<slug:brand_slug>/', views.product_list,name='product_list_by_brand'),
path('<slug:category_slug>/', views.product_list,name='product_list_by_category'),
]
Thank you in advance for your response.
the problem is your upper url pattern is overriding second URL because of same slug and some other reasons.
FIX
change your URL pattern
path('<slug:brand_slug>/brand/', views.product_list,name='product_list_by_brand'),
path('<slug:category_slug>/', views.product_list,name='product_list_by_category'),
Another Thing You Can Do!
modify your function and url pattern.
def product_list(request, slug):
mode = request.GET.get("mode")
if mode.lower() == "brand":
''' your brand code '''
pass
else:
''' your category code '''
pass
path('<slug:slug>/', views.product_list,name='product_list_by_category'),
if you want to execute brand code your URL pattern would look like this.
127.0.0.1:8000/yourslug?mode=brand
and with this url pattern it will execute category code.
127.0.0.1:8000/yourslug
so by default it will execute category code.
I have several urls mapping to one view. Inside the url, I would like to know the url origin? It is to avoid writing multiple views (DRY).
urlpatterns = [
path('path1/', views.IndexView.as_view(), name='index'),
path('path2/', views.IndexView.as_view(), name='index')
]
class IndexView(generic.ListView):
url_origin = ... #would like path1 or path2
I looked for 'reverse' but it does not seem to be a solution to my problem. It returns an error.
reverse('index')
Thank you in advance
You can obtain the original path with request.path [Django-doc] (so in a view function for a class-based view, you can access this with self.request.path.
You can however fix this, for example by providing an extra parameter, like:
urlpatterns = [
path('path1/', views.IndexView.as_view(), name='index1', kwargs={'through': 'path1'}),
path('path2/', views.IndexView.as_view(), name='index2', kwargs={'through': 'path2'})
]
Then you can inspect the self.kwargs['through'] parameter in your class-based view.
Note that you better give the different paths a different name, since otherwise, it will indeed raise an error. By giving these as name 'index1' and 'index2', you can simply use reverse('index1'), and it is not ambiguous to what URL it should redirect.
I have two URL class views from django.contrib.auth:
path('login/', auth_views.LoginView.as_view(
template_name='accounts/login/login.html'), name='my_login'),
path('logout/', auth_views.LogoutView.as_view(
template_name='accounts/logout/logout.html', next_page=XXXX), name='my_logout'),
What's the correct syntax to pass to next_page in the LogoutView? E.g.:
next_page='accounts/login/'
next_page='accounts/login/login.html'
next_page=my_login
next_page='my_login'
next_page=reverse_lazy('my_login')
You can pass my_login as value of next_page as per the implementation. Basically its using resolve_url.
path('logout/', auth_views.LogoutView.as_view(next_page='my_login'), name='my_logout'),
But as #WillemVanOnsem said, you don't need to pass template_name as you will be redirecting to my_login url.
I'm trying to display blog records for particular author using generic view:
urlpatterns = patterns('',
url(r'^blog/(?P<uid>[\d+])/$', ListView.as_view(
queryset=Blog.objects.filter(published=True, author=uid),
), name='blog_list'),
But I get NameError: name 'uid' is not defined
Is it possible to use urlconf named groups this way?
You need to create your own implementation of ListView like so:
class BlogListView(ListView):
model = Blog
def get_queryset(self):
return super(BlogListView, self).get_queryset().filter(
published=True, author__id=self.kwargs['uid'])
and then use it in your URLconf:
urlpatterns = patterns('',
url(r'^blog/(?P<uid>[\d+])/$', BlogListView.as_view(),
name='blog_list'),
The documentation for class-based generic views is, in my opinion, not quite up to scratch with the rest of the Django project yet - but there are some examples which show how to use ListView in this way:
https://docs.djangoproject.com/en/1.3/topics/class-based-views/#viewing-subsets-of-objects