Django - using generic views - python

I am trying to use Django generic view for CRUD.
I found two resources (1, 2), and bit confused the best and easy approach.
Added below to myapp/urls.py
urlpatterns = patterns('',
url(r'^$',
ListView.as_view(
model= Product)),
)
then it gave an error that,
Exception Type: TemplateDoesNotExist
Exception Value:
myapp/product_list.html
It worked when I created a file product_list.html. But, do I have to manually write the template? I am sure not.
Also, how to decorate it so that only users of a group has access to it.
Thanks.

The decorator can be applied inside the urlpatterns like so:
urlpatterns = patterns('',
url(r'^$', my_decorator(ListView.as_view(model= Product))),
)
Yes you have to manually write the template.
Also the name of the template is the_model_name_list.html by default but you can also define a custom template name like so:
urlpatterns = patterns('',
url(r'^$', my_decorator(ListView.as_view(model= Product,
template_name="custom_name.html"))),
)

Related

In django how to generate dynamic url after domain name for every page?

I am building a blog website where I set a unique title for every article. I want the article should have url domain_name/<article_title>/.
Suppose I have model A and Moel B:
class A(models.Model):
title = models.CharField(max_length=500,unique=True)
class B(models.Model):
title = models.CharField(max_length=500,unique=True)
app.urls.py file :
urlpatterns = [
path('',view.index,name="index"),
path('contact/', contact, name="contact"),
path('about/', about, name="about"),
path('terms-and-conditions/', terms, name="terms_and_conditions"),
path('privacy/', privacy, name="privacy"),
path('<str:title>/', article_details, name="article_details"),
]
I have view file as follows:
def article_details(request,title):
if 'title_in_model_A':
render 'some_page_A'
if 'title_in_model_B:
render 'some_page_B'
render(request,'app/404.html')
project.urls file:
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('app.urls')),
]
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
handler404 = 'app.views.view_404'
My question is:
Is this type of page rendering good or not?
Does 404 request handles correctly?
The way OP is doing is ok, but if one wills it's possible to simplify the article_details view by using the shortcut get_object_or_404, like
from django.shortcuts import get_object_or_404
def article_details(request,title):
article = get_object_or_404(A, title=title)
In order to customize the 404 view one can use handlers. Here's a good example in the docs.
Hard to say if OP's renders correctly because the question doesn't show that OP has a clothes app with a view_404 in views.py.
As per OP's new requirement, in the case of having two models and wanting to check the existence of instances that have the title matching a specific one, then OP can use exists() as follows
def article_details(request,title):
if A.objects.filter(title=title).exists():
# render page A
elif B.objects.filter(title=title).exists():
# render page A
else:
# 404
Note that this method is good if one doesn't need the model but are just checking the existence. If one does need it as well, then one can include inside of the condition the following (before the render)
my_model = MyModel.objects.get(title=title)

Can One register namespace in django without adding a URL pattern?

When creating an apphook for the photologue app into django-CMS, I ran into trouble:
"photologue" is not a registered namespace
when trying to reverse an URL such as:
href="{% url 'photologue:pl-gallery-archive-year' date.year %}"
My current Solution is to add a 'foo' url pattern below the cms urls in urls.py so that foo will not ever be matched, but the photologue namespace is registered.
urls.py:
urlpatterns = i18n_patterns('',
url(r'^admin/', include(admin.site.urls)), # NOQA
url(r'^sitemap\.xml$', 'django.contrib.sitemaps.views.sitemap',
{'sitemaps':
{
'cmspages': CMSSitemap,
'photologue_galleries': GallerySitemap,
'photologue_photos': PhotoSitemap,
}}),
url(r'^', include('cms.urls')),
url(r'^foo/', include('photologue.urls', namespace='photologue')),
)
cms_app.py:
class GalleriesApphook(CMSApp):
name = _("Galleries Apphook")
urls = ["photologue.urls"]
app_name = "photologue"
apphook_pool.register(GalleriesApphook)
My question is: Is there a cleaner way to do this ? Like a "register_namespace" function in the django core ?
EDIT
I found something "slightly cleaner" in the imagestore doc. In order not to pollute urls they re-include the cms ones with the namespace.
url(r'^', include('cms.urls', namespace='imagestore'))
I had exactly the same problem. I solved it with #stefanfoulis hint to add application instance name. I did not have app_name when starting this at first time.

Handling Multiple Views/ Multiple Urls in Django

I'm having the 404 error when trying to handle a view that is not related to the main page. For example, if I initially start at the main page home, and want to navigate to another page called, otherpage, I receive a 404 otherpage.html not found.
The way I'm doing is based off intuition. So if there's a better way to do this, please mention it:
in the file:
prd/
views.py
url.py
otherstuffthatshouldbehere.py..
I have views.py (this is where I think the error is):
from django.shortcuts import render
def home(request):
context = {}
template = "index.html"
return render(request, template, context)
def otherpage(request):
context = {}
template = "otherpage.html"
return render(request, template, context)
Then urls.py:
from django.conf.urls import patterns, include, url
from django.contrib import admin
urlpatterns = patterns('',
url(r'^$', 'prd.views.home', name='home'),
url(r'^$', 'prd.views.otherpage', name='otherpage'),
url(r'^admin/', include(admin.site.urls)),
)
This returns a 404 for the otherpage.html. I have the template directory working fine. But how do I go about handling multiple views?
EDIT:
Upon adding:
url(r'^otherpage$', 'prd.views.otherpage', name='otherpage'),
I received this error:
Using the URLconf defined in prd.urls, Django tried these URL patterns, in this order:
^$ [name='home']
^about$ [name='about']
^projects$ [name='projects']
^admin/
The current URL, about.html, didn't match any of these.
The urlpatterns starts at the top and then goes down until it matches a URL based on the regex. In order for Django to serve up the page located at otherpage.html there has to be a URL defined in urlpatterns that matches otherpage.html otherwise you will get the 404.
In this case you have:
url(r'^$', 'prd.views.home', name='home'),
url(r'^$', 'prd.views.otherpage', name='otherpage'),
Note that nothing will ever get to otherpage here because home has the same pattern (regex) and will therefore always match first. You want to have a different URL for both those so that you can differentiate between them. Perhaps you could do something like:
url(r'^$', 'prd.views.home', name='home'),
url(r'^otherpage.html$', 'prd.views.otherpage', name='otherpage'),
After making this change you now have a match for otherpage and hopefully no more 404.
EDIT:
url(r'^otherpage.html$', 'prd.views.otherpage', name='otherpage'),
This matches www.example.com/otherpage.html but it will not match www.example.com/otherpage
To match www.example.com/otherpage you need to use:
url(r'^otherpage$', 'prd.views.otherpage', name='otherpage'),
Note the difference in the regex, there's no .html here. The regex matches exactly what you put in it.

string as second argument in url dispatcher for CBV

Before class based views my urls.py looked like that:
urlpatterns= patterns('mypackage.views',
url(r'^$', 'home', name='home'),
url(r'other', name='other'),
)
Now my home view is class based. As i like uniformity, I do not would like to keep the view class as string. I tried:
urlpatterns= patterns('mypackage.views',
url(r'^$', 'Home.as_view', name='home'),
url(r'Other.as_view', name='other'),
)
and I get Parent module mypackage.views.Home does not exist . If I simply give the class name like:
urlpatterns= patterns('mypackage.views',
url(r'^$', 'Home', name='home'),
url(r'Other', name='other'),
)
I get: __init__ takes exactly 1 argument, 2 given
Is there a way to pass a string as second argument to the url function for CBV as for FBV instead of from mypackage.views import * ?
EDIT:
There seems to be no built-in solution for this. In this case: why are strings as second parameter allowed for the url function: Doesn't it violate the zen ("there is only one way to do this)?
You should import the class-based view and specify them that way:
from mypackage.views import *
urlpatterns = patterns('mypackage.views',
url(r'^$', Home.as_view(), name='home'),
url(r'other', Other.as_view() name='other'),
)
Also note that your url() calls should have three parameters: the URL pattern, the view and name (some examples you wrote don't have all of these).
If you want to pass your view as string, then in your views do this:
class Home(View):
pass
home = Home.as_view()
then in your url:
url(r'^$', 'mypackage.views.home', name='home'),
You need to use full path.

Django redirect "/" to index of installed app

I'trying to redirect the / of my domain to point to a index in my "frontend" app.
I tried a lot of ways and all of them work.
The problem is that my index_view is being called twice for every redirect.
Here is my top urls.py
urlpatterns = patterns('',
url(r'^$', lambda x: HttpResponseRedirect('/frontend/')),
url(r'^frontend/', include('frontend.urls', namespace="frontend")),
)
And here is my frontend/urls.py
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^alert/create/$', views.create_alert, name="create_alert"),
url(r'^alert/edit/(\w+)', views.edit_alert, name="edit_alert"),
)
Every time I go to / is calling my views.index twice and I can't see why =/
Am I doing the redirecting wrong ?
Thanks in advance for any help!
You can set the root to use your FE url patterns like this:
urlpatterns = patterns('',
url(r'^', include('frontend.urls', namespace="frontend")),
)
If you wanna forcibly redirect to /frontend/ then you will need a view to handle the redirect.
Maybe look at the Redirect Generic view: https://docs.djangoproject.com/en/1.1/ref/generic-views/#django-views-generic-simple-redirect-to

Categories

Resources