I have a view that either displays a form or a 'thank you' page (if the form submission was successful). I am using redirect with a url that I have tested working to display the thank-you page.
def form8(request):
form = UserInfoForm(request.POST or None)
if form.is_valid():
form.save()
return redirect('/sjwork/thanks')
return render(request, 'form8.html', {'form': form})
However, when the form is successfully submitted django give the error:
ViewDoesNotExist at /sjwork/form8
Could not import views. Error was: No module named views
As said, I can go to localhost:8000/sjwork/thanks directly and it displays the thank-you page. According to documentation I can use a hard-coded url like this. I tried alternatives, too (giving the view, using a full url like http://google.com) - nothing works. I must be missing something basic here. Would appreciate if someone can explain what is going on here. Thanks.
The app 'sjwork' has the following in its urls.py:
url(r'^$', 'views.home', name='home'),
url(r'^thanks$', 'sjwork.views.thanks'),
url(r'^form8$', 'sjwork.views.form8', name='form8'),
whereas the project urls.py contains:
url(r'^sjwork/', include('formtest.sjwork.urls')),
Looks like error is related to this pattern.
url(r'^$', 'views.home', name='home'),
Try removing it and try again.
Also, Could you include your import statements in your question.
Related
I've been dealing with Django recently and I have a problem with the above error, since yesterday I don't know how to deal with it, I'm sending a code snippet and asking for help with an explanation.
Thank you very much in advance
`from django.urls import path
from crm_app import views
app_name='crm_app'
urlpatterns=[
path('', views.submissions_list, name='submissions_list'),
path('int:year/int:month/int:day/slug:detail/', views.submissions_detail, name='submissions_detail'),
path('int:year/int:month/int:day/slug:detail/edit', views.edit, name='edit'),
]`
def edit(request,year,month,day,detail): edit=get_object_or_404(Submissions, slug=detail, complex__year=year, complex__month=month, complex__day=day) form = StatusForm(request.POST or None, instance=edit) if form.is_valid(): form.save() return redirect(submissions_list) return render(request, 'form.html', {'form':form})
I've tried different combinations of links but none work
Exactly, the point is that when I am in detail, I would like to be moved from this place to editing the current element
I have experienced using reverse within get_absolute_url method in the model, but I wish I have an idea about the difference between reverse and redirect, I have tried to search on google about it but there is almost nothing
I don't know what should I write also to convince stack overflow that I don't have any other description
Reverse and redirect have a different meaning. Here is a simple explanation:
reverse in Django is used to find the URL of a given resource. Let's say that you have a blog website and from the main page, you want to provide links to your blog posts. You can of course just hard-code /posts/123/ and just change the ID of your blog post in URL, but that makes it hard to change your URL for the post in the future. That's why Django comes with reverse function. All you need to do is to pass the name of your URL path (defined in your urlpatterns) and Django will find for you the correct URL. It is called reverse because it is a reverse process of determining which view should be called for a given URL (which process is called resolving).
Redirects are not specific to Django or any other web frameworks. Redirect means that for a given URL (or action), the user should be instructed to visit a specific URL. This can be done by sending a special redirect request and from there the browser will handle it for the user, so no user action is required in that process. You can use reverse in redirect process to determine the URL that the user should be redirected to.
GwynBleidD has given you the answer, but there is a reason why you might be getting confused. The Django redirect shortcut accepts arguments in several different forms. One of them is a URLpattern mane, with arguments, that is then passed to reverse to generate the actual URL to redirect to. But that's just a shortcut, to enable a common pattern.
here's an example
app/views
#imports
def indexView(request):
....
return render(request, 'index.html', context)
def loginView(request):
....
return redirect('index')
def articleDetailView(request, id):
....
return redirect(reverse('article-comments', kwargs={'id':id})
def articleCommentsView(request, id):
....
return render(request, 'comment_list.html', context)
proj/urls
#imports
urlpatterns = [
....,
path('', include(app.urls))
]
app/urls
#imports
urlpatterns = [
....,
path('index/', index, name='index'),
path('login/', loginView, name='login'),
path('article/<int:id>/detail', articleDetailView, name='article-detail'),
path('article/<int:id>/comments/',articleCommentsView, name='article-comments')
....,
]
For loginView redirect will return url as-is i.e. 'index' which will be appended to base(project) urlpatterns. Here redirect(reverse('index')) will also work since kwargs is None by default for reverse function and 'index' view doesn't require any kwarg. It returns '/index/' which is passed to redirect(which again will be appended to base urls).
One thing to note is that reverse is used to make complete url - needed for redirect - that is shown in 'articleDetailview'.
The most basic difference between the two is :
Redirect Method will redirect you to a specific route in General.
Reverse Method will return the complete URL to that route as a String.
I am having a problem with HttpResponseRedirect in Django. It seems that, whatever parameters I try, it either throws an error, or it redirects without changing the URL. I am using it on a custom login_user view, and I want the URL in the address bar to change after they are redirected. If I use redirect instead of HttpResponseRedirect, it does not change. Either way, I can get it to serve the correct template, but the URL stays the same. Being new to Django, it would be helpful if someone could explain to me how to do this and why my current code is not working.
I have seen a couple of similar questions to mine on Stack Exchange, but the answers have not helped.
Here are the relevant parts of my views.py (please note the indenting has gone weird due to copying and pasting in here, and is not the cause of the error).
from django.http import *
from django.contrib.auth import authenticate, login, logout
def login_user(request):
logout(request)
username = password = ''
if request.POST:
username = request.POST.get('username')
password = request.POST.get('password')
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request, user)
return HttpResponseRedirect('dashboard')
else:
state = "Your account is not active, please contact the app administrator."
else:
state = "Your username and/or password were incorrect."
state = "Please log in below..."
context = RequestContext(request, {
'state': state,
'username': username,
})
return render_to_response('bank/auth.html', {}, context)
dashboard is the name of another view, and it works fine in a redirect from my index view. I've also tried hard-coding the url in, but that doesn't work either. Any suggestions?? Thanks.
If you use HttpResponseRedirect, you must provide the url, not the name of the url.
You can either get the url by using reverse:
from django.core.urlresolvers import reverse
def my_view(request):
...
return HttpResponseRedirect(reverse('dashboard'))
or by using the redirect shortcut.
from django.shortcuts import redirect
def my_view(request):
...
return redirect('dashboard')
If using the either of the above approaches does not work, then there's probably a mistake somewhere else in the view. It's difficult to tell where, since the indentation is incorrect. Try adding some logging or print statements to see if you are really returning the redirect where you think you are.
In this particular case, the problem wasn't anything to do with my view code, it was actually a problem caused through using JQuery mobile. I found the answer here: Error with Redirects in JQuery Mobile which was to set the data-url attribute on the page div.
However, I have up-voted Alasdair's answer, as his way is the correct one of the ways I had tried.
I personally prefer the simple way as follows:
In urls.py:
url(r'^dashboard/$', 'appname.views.dashboard_view', name='dashboard_view'),
In views.py:
from django.http import HttpResponseRedirect
def dashboard_view(request):
...
return HttpResponseRedirect('/dashboard/')
We have middleware that records the last url the user has visited:
class LastSiteUrl(object):
def is_admin_url(self, url):
if re.search('^(http:\/\/.*){0,1}\/admin\/', url) is None: return(False)
else: return(True)
def process_request(self, request):
if self.is_admin_url(request.path) and \
not self.is_admin_url(request.META['HTTP_REFERER']):
request.session['last_site_url'] = request.META['HTTP_REFERER']
We use this to return them back to the last app page they were at,
from an admin page, no matter how deep into admin they were. This is
working fine.
We have a custom 404 page, and from there I want to provide a link to
take them back to where they were in the app. But it seems the
middleware does not run when they go to an invalid page. Is there a
way to make it run in that case as well?
If you use handler404 in your base urls.py you can serve your 404 page from a django view instead of straight from the server, and add that middleware the way you would to any other django view.
https://docs.djangoproject.com/en/dev/ref/urls/#django.conf.urls.handler404
in urls.py
handler404 = 'app.views.view'
or
handler404 = ClassView.as_view()
I don't know if this was the answer 10 years ago, but I've encountered the same issue myself and found that Abdul Aziz Barkat's answer to my question, " Why is the Middleware not processed on 404 page in Django? " was the right answer for me: to use a custom context processor instead of middleware.
The answers suggesting using handler404 led me down a long and unproductive rabbit hole.
I'm in c.html (http://localhost:8000/practice/c) and I click a link that changes my url to
http://localhost:8000/practice/c/?q=1
this is urls.py
url(r'^$', prac_c),
url(r'^q=\d',fetch_c),
and this is views.py
def prac_c(request):
return render_to_response('subject/c.html', {"problem_list":problem_list})
def fetch_c(request):
qno = request.GET.get('q')
if qno:
return render_to_response('subject/que.html', {'qno':qno}, context_instance=RequestContext(request))
but I'm not getting directed to que.html. Something wrong with the urls.py?
What the URLconf searches against
The URLconf searches against the requested URL, as a normal Python string. This does not include GET or POST parameters, or the domain name.
source