Reverse for 'crm_app.views.submissions_list' not found. 'crm_app.views.submissions_list' is not a valid view function or pattern name - django-views

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

Related

Django. 301 Redirect from old URL to new

Hello! Please tell me how to organize a redirect correctly.
There is an old version of the site and a new one. In the old version (another CMS, not Django) the objects have their own URL, in the new revised scheme, and the objects have a different URL.
In each object on the new site, there is a completed field with the old URL. In model.py it looks like this:
old_url = models.CharField('Old URL', blank=True, max_length=100)
I specifically moved the old url to a separate field. Or was it not necessary to do this?
Question. How to set up a redirect correctly, so that after going to the object using the old URL, the site visitor will be redirected to the new URL of this object?
IMHO, I don't think writting old_url for each and every object is pretty inefficient. Instead you can implement a custom 404 view, and handle the redirection there.
I think you can create some regex or plain url maps to new url and redirect accordingly.
import re
from django.http import HttpResponseNotFound
OLD_URL_MAP = { 'old_url_regex': 'new_url_path'}
def handler404(self, request):
for old_re, new_url in OLD_URL_MAP.items():
if re.match(old_re, request.path):
return redirect(new_url, request.resolver_match.kwargs)
return HttpResponseNotFound('not found')
# inside urls.py
handler404 = 'myapp.views.handler404'
Here I have used a map hard coded in python, you can create a model for that as well.
Update
A costly solution is to use middleware. You can try like this:
import re
from django.urls import resolve
OLD_URL_MAP = { 'old_url_regex': 'new_url_path'}
class RerouteMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
try:
resolve(request.path_info) # trying to find if the current url exists in your django project. if not, it will throw exception.
except:
for old_re, new_url in OLD_URL_MAP.items(): # iterating through urls
if re.match(old_re, request.path):
return redirect(new_url, request.resolver_match.kwargs)
response = self.get_response(request)
return response
And add that middleware at the bottom of MIDDLEWARE settings.
FYI, its a regex based solution, assuming those urls are dynamic. Instead you can use plain text urls, but its up to you.
Use redirect() from django.shortcuts [the same library from where you import render]. Also, assuming, that the old_url contains only the relative url.
from django.shortcuts import render, redirect
def someView(request):
q = ~some queryset returning the current object~
current_url = request.get_full_path().strip("http://www.example.com/")
if q.old_url == current_url:
redirect(q.new_url)
else:
pass
Remember, redirect() returns an HttpResponse.

Remove "?id=" from dynamic URLs

I'm pretty new to django and i'm working on a website that needs a dynamic URL for a database table, and it all works fine, but i would like to know how to remove the "?id=" from the url, so rather than
localhost:8000/dynamicurl/?id=XXXXX
The url becomes
localhost:8000/dynamicurl/XXXXX
Instead
I did a fine amount of searching in the documentation and didn't find a lot, though it's pretty likely i missed something.
EDIT:
thanks everyone for helping, the simplest answer was to remove the object i was using to fetch the ID and just replace it for ID in evert instance,
so my url became
url(r'^dynamicurl/(?P[0-9]+)/$', views.dynamicurl)
and my view became
def dynamicurl(request, id):
i'm like very very new to django FYI
you can capture a variable in url definition in the apps urls.py file. It would look something like this:
url(r'^dynamicurl/(?P<id>[0-9]+)?$', dynamicurl, name = 'dynamicurl'),
then in your view function you receive that parameter:
def dynamicurl(request, id):
If you are talking about how to change your url inside the urls, I suggest you to use code that already answered above: https://stackoverflow.com/a/41988051/6396981
But, if you talking about how to redirect localhost:8000/dynamicurl/?id=XXXXX to localhost:8000/dynamicurl/XXXXX, hope this usefull..
1. views.py
from django.http import HttpResponse
from django.views.generic.base import RedirectView
from django.core.urlresolvers import reverse
class RedirectView(RedirectView):
permanent = False
def get_redirect_url(self):
get_id = self.request.GET.get('id')
if get_id is not None:
return reverse('redirected_page', kwargs={'id': id})
return reverse('origin_page')
def redirected_view(request, id):
# your final view goes here...
return HttpResponse("You're looking for id: %d." % id)
2. urls.py
from django.conf.urls import url
from yourapp.views import views (RedirectView, redirected_view)
urlpatterns = [
# first view the pool to doing redirection
url(r'^pool/$', RedirectView.as_view(), name='origin_page'),
# the final url
url(r'^pool/(?P<id>[\d]+)/$', redirected_view, name='redirected_page'),
]

HttpResponseRedirect not working Django 1.7

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/')

django redirect not working as expected

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.

Django odd problem with using reverse and url tag

I've found very odd thing about using reverse in Django 1.2.1.
I have:
myapp/
views.py
urls.py
in urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns('myapp.views',
url(r'^$', 'browse'),
)
in views.py
from django.shortcuts import render_to_response
from django.core.urlresolvers import reverse
print reverse('myapp.views.browse') # <----- this will print correct value
def browse (request):
print reverse('myapp.views.browse') # <----- this fails with exception
return render_to_response('myapp/browse.html')
When I put reverse method anywhere outside the view method (browse - in this case) I get an exception in every further use of reverse or {% url %} tag.
NoReverseMatch at /
Reverse for 'myapp.views.browse' with arguments '()'
and keyword arguments '{}' not found.
WTF? When I comment/delete the print line outside browse() , second print line inside browse() magically start working!
The most basic case is:
class MyForm(forms.Form):
field = forms.CharField(default=reverse(....))
def some_view(request):
print reverse(...)
....
1) I define a class in main-scope that is initialized when django initialize (and runs reverse)
2) When a request comes the some_view function has been triggered and it evaluates the reverse function again (and fails with exception).
I don't see anything bad at all in this approach. Why not to initialise some values in the django main-scope with results of the reverse() function ?
You will probably need to pass 'request' as the second parameter when calling reverse() from within the view function after it's already been called.
def browse(request):
print reverse('myapp.views.browse', args=[request])
This is odd behavior indeed, but this might possibly be a solution for now.
First, you should be naming your URLs in order to use reverse. That is the correct approach AFAIK.
Second, why are you calling reverse from within a FormField? I really don't get it.
Maybe you could enlighten us by posting the full code rather than a curated set of snippets.
# urls.py
url(r'^/$', 'home_view', name='home'),
url(r'^login/$', 'login_view', name='login'),
# views.py
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.http import HttpResponseRedirect
def login_view(request):
# do login stuff and redirect to home
return HttpResponseRedirect(reverse('home'))
def home(request):
# do home stuff
return render_to_response("home.html", locals(), context_instance=RequestContext(request))
The problem is caused by import hell in python. reverse depends on other things and cannot be used while initialization.
The solution is to use lazy reverse. E.g. using this:
http://djangosnippets.org/snippets/499/