I am trying to make a view that i can use in multiple apps with different redirect urls:
Parent function:
def create_order(request, redirect_url):
data = dict()
if request.method == 'POST':
form = OrderForm(request.POST)
if form.is_valid():
form.save()
return redirect(redirect_url)
else:
form = OrderForm()
data['form'] = form
return render(request, 'core/order_document.html', data)
Child function:
#login_required()
def admin_order_document(request):
redirect_url = 'administrator:order_waiting_list'
return create_order(request, redirect_url)
When i'm trying to call admin_order_document function i'm getting:
Traceback (most recent call last):
File "/home/project/venv/lib/python3.5/site-packages/django/core/handlers/exception.py", line 41, in inner
response = get_response(request)
File "/home/project/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/home/project/venv/lib/python3.5/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
TypeError: create_order() missing 1 required positional argument: 'redirect_url'
If i remove redirect_url from both functions and manually add 'administrator:order_waiting_list' to redirect() it works, but i need to redirect to multiple urls. So, why am i getting this error?
url(r'^orders/create/', views.create_order, name='create_order')
This clearly is not going to work, since create_order requires redirect_url but there is no redirect_url kwarg in the regex r'^orders/create/'.
Perhaps you want to use the admin_order_document view here instead:
url(r'^orders/create/', views.admin_order_document, name='create_order')
Note you should add a trailing dollar, i.e. r'^orders/create/$' unless you want to match orders/create/something-else as well as orders/create/.
If you didn't changed the regular url
urlpatterns = [
url(r'^admin/', admin_site.urls),
...
]
of your admin site you need to call your function like that:
#login_required()
def admin_order_document(request):
redirect_url = 'admin:order_waiting_list'
return create_order(request, redirect_url)
That should fix your problem.
Related
I don't seem to find a way to solve an error happening at the user authentication.
User needs to login at the public website level let's say localhost/login and when he/she is authenticated, I need the user to be redirected in the corresponding sub domain, for example demo.localhost. This is not working for me so far, even after checking some posts about the subject.
Here is the views.py in customers.views where user log in:
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(request,data=request.POST)
print("form login view")
if form.is_valid():
print("checkpoint")
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
user = form.get_user()
schema_name = user.schema_name
print(user)
if user is not None:
login(request, user)
url = reverse(schema_name + '.localhost:8000/mydashboard/')
print("url")
return HttpResponseRedirect(url)
else:
print("not working")
form = AuthenticationForm()
context = {
'form': form,
}
return render(request, 'login.html', context)
here is what urls in the core folder:
urlpatterns = [
path('admin/', admin.site.urls),
path('django_plotly_dash/', include('django_plotly_dash.urls')),
path('mydashboard/', include('mydashboard.urls',namespace="mydashboard")),
]
and I have added app_name = 'mydashboard' in mydashboard.urls
Here is the traceback of the error I keep getting:
Internal Server Error: /registration/loginUser
Traceback (most recent call last):
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/urls/base.py", line 71, in reverse
extra, resolver = resolver.namespace_dict[ns]
KeyError: 'demo.localhost'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/pierre/Desktop/simulation_application/customers/views.py", line 65, in login_view
url = reverse(schema_name + '.localhost:8000/mydashboard/')
File "/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/urls/base.py", line 82, in reverse
raise NoReverseMatch("%s is not a registered namespace" % key)
django.urls.exceptions.NoReverseMatch: 'demo.localhost' is not a registered namespace
UPDATE:
Remove the reverse and included request.scheme in the url.
def login_view(request):
if request.method == 'POST':
form = AuthenticationForm(request,data=request.POST)
print("form login view")
if form.is_valid():
print("checkpoint")
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
user = form.get_user()
schema_name = user.schema_name
print(user)
if user is not None:
login(request, user)
print(request.scheme)
url = request.scheme + '://' + schema_name + '.localhost:8000/mydashboard/'
print("url",url)
return HttpResponseRedirect(url)
else:
print("not working")
form = AuthenticationForm()
context = {
'form': form,
}
return render(request, 'login.html', context)
this is still working and output the following error:
response = get_response(request) …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/core/handlers/base.py, line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs) …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/contrib/auth/decorators.py, line 32, in _wrapped_view
return redirect_to_login( …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/contrib/auth/views.py, line 190, in redirect_to_login
return HttpResponseRedirect(urlunparse(login_url_parts)) …
Local vars
/Users/pierre/opt/anaconda3/lib/python3.9/site-packages/django/http/response.py, line 507, in __init__
raise DisallowedRedirect("Unsafe redirect to URL with protocol '%s'" % parsed.scheme) …
Local vars
Unsafe redirect to URL with protocol 'localhost'
Bad Request: /mydashboard/simulations_list
HTTP GET /mydashboard/simulations_list 400 [0.09, 127.0.0.1:50218]
This is strange because the requested url is perfectly working url, registered and accessible without a problem before trying to redirect to it after the login
EDIT #2:
Found out that the above code works when the target url does not require login required
# this does not work
#login_required
def simulationslistView(request,):
return render(request, 'simulations_list.html')
# this works
def simulationslistView(request,):
return render(request, 'simulations_list.html')
I am obviously make sure that the app is secured and can only be accessed by logged in users. Is there a work around to make sure it works?
reverse is an internal django utility to go from "app name" + ':' + "url friendly name" to "real url". In your example, you're already providing the "real url".
Quit while you're ahead and just do:
if user is not None:
login(request, user)
url = request.scheme + '://' + schema_name + '.localhost:8000/mydashboard/'
print("url")
return HttpResponseRedirect(url)
Notice no reverse
Notice the adding of the URL scheme (http/https determined by how the request was originally made)
I am trying to create a form(boqform) to post data into a model(boqmodel)
but I am getting this
typeerror is_valid() missing 1 required positional argument: 'self'
I need to display a form called boqform on html template and post the data user entered into boqmodel
my view:
def boqmodel1(request):
if boqform.is_valid():
form = boqform(request.POST)
obj=form.save(commit=False)
obj.save()
context = {'form': form}
return render(request, 'create.html', context)
else:
context = {'error': 'The post has been successfully created. Please enter boq'}
return render(request, 'create.html', context)
Traceback:
File "C:\Users\TRICON\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\exception.py" in inner
34. response = get_response(request)
File "C:\Users\TRICON\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "C:\Users\TRICON\AppData\Local\Programs\Python\Python38-32\lib\site-packages\django\core\handlers\base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\TRICON\Desktop\ind\ind\boq\views.py" in boqmodel1
23. if boqform.is_valid():
Exception Type: TypeError at /boq/create/
Exception Value: is_valid() missing 1 required positional argument: 'self'
You're trying to call the instance function is_valid() on the class boqform. You need to get an instance of boqform first. Switching lines 1 and 2 of the function should fix the issue:
def boqmodel1(request):
form = boqform(request.POST)
if form.is_valid():
obj=form.save(commit=False)
obj.save()
context = {'form': form}
return render(request, 'create.html', context)
else:
context = {'error': 'The post has been successfully created. Please enter boq'}
return render(request, 'create.html', context)
I must be going crazy...
If I have my views.py file with 48 or less lines, when I POST data to it, I see
Incomplete response received from application
However, If I have 49 lines or more I get a
NameError, 'request' is not defined
thrown on line 31 and 49, even if line 31/49 is empty.
Could someone please explain what is happening?
Also btw Django Admin - "Incomplete response received from application" does not answer my question.
veiws.py:
from django.shortcuts import render
from django.shortcuts import render
from django.shortcuts import HttpResponse
from django.core.exceptions import *
from datetime import datetime
def remove_xss(chat, request):
return chat
def find_urls(chat, request):
new_chat = ' '.join([('{}'.format(word, word) if ('http://' in word or 'https://' in word) else word) for word in chat.split(' ')])
return new_chat
def format_chat(chat, username, request):
chat = remove_xss(chat, request)
chat = find_urls(chat, request)
request = request
return "hi"
def chat_index(request):
return render(request, 'chatroom.html')
def chat(request):
if request.method == 'POST':
chat = request.POST.get('textfield', None)
if request.user.is_authenticated():
u = request.user.username
f_chat = format_chat(chat, u, request)
else:
return HttpResponse('You must be signed in to continue')
with open('chats.txt', 'a') as chats:
chats.write(f_chat)
return render(request, 'chatroom.html')
urls.py: (Working (i think))
from chat import views
from django.urls import path
urlpatterns = [
path('/', views.chat_index),
path('chat/', views.chat)
]
Full Traceback: (when there is >=49 lines)
Traceback:
File "/home/raveivcs/virtualenv/backend/3.5/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
34. response = get_response(request)
File "/home/raveivcs/virtualenv/backend/3.5/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
115. response = self.process_exception_by_middleware(e, request)
File "/home/raveivcs/virtualenv/backend/3.5/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
113. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/home/raveivcs/backend/chat/views.py" in chat
49.
File "/home/raveivcs/backend/chat/views.py" in format_chat
31.
Exception Type: NameError at /chat/chat/
Exception Value: name 'request' is not defined
Ok, for anyone coming here, all you need to do is look in different files. The error doesn't have to be in the file you think it is in.
After succesfully registering, the user is redirected to the template 'registration_done.html'.
Is there any way of changing this behaviour to redirecting the user to the registration page and displaying a message?
I tried these code below also tried different ways to change it but have different types of errors in different cases.
urls.py
url(r'^register/$',
views.register,
{
'success_url': '/accounts/register/?success=true'
},
name='register'),
view.py
def register(request):
if request.method == 'POST':
user_form = UserRegistrationForm(request.POST)
if user_form.is_valid():
# Create a new user object but avoid saving it yet
new_user = user_form.save(commit=False)
# Set the chosen password
new_user.set_password(user_form.cleaned_data['password'])
# Save the User object
new_user.save()
success = request.GET.get('success', None)
return render(request, {'new_user': new_user, 'success': success})
else:
user_form = UserRegistrationForm()
return render(request, 'account/register.html', {'user_form': user_form})
registration.html:
{% if success %}
<p>{% trans 'Successfull registration!' %}</p>
{% endif %}
Whats wrong I did?!
Error:
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 149, in get_response
response = self.process_exception_by_middleware(e, request)
File "C:\Python34\lib\site-packages\django\core\handlers\base.py", line 147, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
TypeError: register() got an unexpected keyword argument 'success_url'
[18/Aug/2016 14:17:55] "GET /en/account/register/ HTTP/1.1" 500 59886
You are trying to pass the kwarg success_url to your function register
Your function register(request) only accepts one argument: 'request'.
So you can accept a second argument, say success_url, like so
def register(request, success_url):
...
But there is no point doing that if success_url is a constant. In that case, just define it your register function
def register(request):
success_url = 'foo'
Another point here is that you want to reverse that url, rather than hard code it.
Also I'm not sure why you would want to use this:
success = request.GET.get('success', None)
Any user could submit their own success variable in the GET request. Are you expecting this from a form? Looks like a security vulnerability if the user can just say that the were successful in request.GET.
Right now you aren't actually rendering a template on success anyway because you are missing a template name/path from your first render call.
So either add a template or redirect them to another page.
i am trying to use django reverse to route back to a page which take an argument vendor_id.
I am trying to do it this way using this post as reference: POST
return HttpResponseRedirect(reverse('vendor_data', kwargs={'vendor_id':vendor_id}))
My view method which should be called:
def vendorData(request):
vendors = Vendors()
if request.method == 'GET':
vendor_id = request.GET.get('vendor_id')
if vendors.checkValidVendorId(vendor_id) == False:
return HttpResponse('<h2>404<br>Invalid Vendor Id.</h2>')
else:
vendor_details = vendors.getVendorData(vendor_id)
.....
return render(request, 'vendor_data.html', context_dict)
my urls.py:
url(r'^vendor_data/', views.vendorData, name='vendor_data'),
If i dont pass any argument then it shows the HttpResponse from my views method.
If i pass argument vendor_id like this:
return HttpResponseRedirect(reverse('vendor_data', kwargs={'vendor_id':vendor_id}))
It throws an error. The traceback is:
Traceback:
File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Users\Manish\Desktop\ScratcherAdmin\ScratcherAdmin\vendors\views.py" in editVendorData
162. return HttpResponseRedirect(reverse('vendor_data', kwargs={'vendor_id':vendor_id}))
File "C:\Python27\lib\site-packages\django\core\urlresolvers.py" in reverse
579. return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "C:\Python27\lib\site-packages\django\core\urlresolvers.py" in _reverse_with_prefix
496. (lookup_view_s, args, kwargs, len(patterns), patterns))
Exception Type: NoReverseMatch at /update_vendor_data/
Exception Value: Reverse for 'vendor_data' with arguments '()' and keyword arguments '{'vendor_id': u'20150001'}' not found. 1 pattern(s) tried: ['vendor_data/']
How to solve this?
What you are expecting inside your view is a GET parameter from query string. Something your expected URL should be something like,
www.example.com/vendor/?vendor_id=12345
And below,
return HttpResponseRedirect(reverse('vendor_data', kwargs={'vendor_id':vendor_id}))
will redirect you to something like,
www.example.com/vendor/12345
For which your view should expect an additional parameter vendor_id,
def vendorData(request, vendor_id):
and accordingly your rest of the code might change.
Solution to your problem:
return HttpResponseRedirect("{}?vendor_id={}".format(reverse('vendor_data'), vendor_id))