when I try to render a page does not work, here's a quick example, what I do is to send data from a form from the html with a button,
and then redirect it to another page.
The data arrive correctly and I've checked from the server.
views.py
def index(request):
context={}
if request.method == 'POST': # If the form has been submitted...
form=list(dict(request.POST)['data[]'])
return render(request,'bala/pdf.html',{'form':form})
else:
return render(request,'bala/index.html',context)
Related
I'm building a website, to be used in dental practices, however I'm having trouble with the URL routing. I'm wanting af URL pattern like: Denthelp/kartotek/#nameofclinic#/opretpatient.
My suggestion looks like this:
urls.py:
path('kartotek/<str:kl_id>/', views.kartotek, name="kartotek"),
path('kartotek/<str:kl_id>/opretpatient/', views.opretpatient, name="opret_patient"),
Views. py:
def kartotek(request, kl_id):
kliniknavn = Klinik.objects.get(navn=kl_id)
E_patient = kliniknavn.patient_set.all()
context = { 'kliniknavn':kliniknavn, 'E_patient':E_patient}
return render(request,'DentHelp/kartotek.html', context )
def opretpatient(request, kl_id):
kliniknavn = Klinik.objects.get(navn=kl_id)
form = PatientForm()
if request.method == 'POST':
form = PatientForm(request.POST)
if form.is_valid():
form.save()
return redirect('kartotek/<str:kl_id>/')
context = {'form':form, 'kliniknavn':kliniknavn}
return render(request,'DentHelp/kartotek/<str:kl_id>/opretpatient.html', context)
When running code I get an OSError for the last line of code shown here.
Have you guys have any advise for this to work?
You are mixing up render with redirect. render renders a template dynamically with attributes from context, where redirect redirects the user to a different view. To call render, you need to provide template name and context. For redirect, you need to provide url name and parameters (if required). Here is how you should do in your code:
def opretpatient(request, kl_id):
kliniknavn = Klinik.objects.get(navn=kl_id)
form = PatientForm()
if request.method == 'POST':
form = PatientForm(request.POST)
if form.is_valid():
form.save()
return redirect('kartotek', kl_id) # url name and parameter
context = {'form':form, 'kliniknavn':kliniknavn}
return render(request, 'DentHelp/kartotek/opretpatient.html', context) # template name and context
I'm working on a blog build on django and doing the comment stuff and I would like to build it from scratch here my views function:
def topic_detail(request, slug):
topic = get_object_or_404(Topic, slug=slug)
form = CommentForm()
if request.method == 'POST':
if request.user.is_authenticated:
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.topic = topic
comment.created_by = request.user
comment.save()
return redirect('board:topic_detail', slug=topic.slug)
else:
redirect('accounts:login')
else:
form = CommentForm()
return render(request, 'topic.html', {'topic':topic, 'form':form})
my page layout would be:
< ............................>
Something I want to write
<.............................>
Comment Field
<.............................>
Comments
So when user presses the button, server will check if that user is authenticated. If yes comment is updated, If no user will be directed to login views. Here the problem, when I'm logged in everything works fine, but when I log out test the views, It does not redirect me to the login views but just reload the page. I would appreciate if you help me.
Thanks!
You should use return redirect(....) instead of just redirect(...) to return the actual HttpResponse. Now your code continues to the last line and renders the same page again.
Views.py
def form_name_view(request):
form = FormName()
if request.method == "POST":
form = FormName(request.POST)
if form.is_valid():
form.save(commit=True)
return HttpResponseRedirect('/') # return index(request)
else:
print('INVALID FORM INPUTS')
return render(request, 'first_app/form_page.html', {'form': form})
When I use HttpResponseRedirect to get back to my index page, then everything works correct, but the concern is if I use calling index method instead of HttpResponseRedirect then the behavior is a little bit insane:
After reaching index page if I hit refresh then alert appears says:
The page that you're looking for used information that you entered.
Returning to that page might cause any action you took to be
repeated. Do you want to continue?
If i want to get back to the same form page, by calling that same method again like
return form_name_view(request)
The new form is already filled with previous inserted data, with the message on the form
Topic with this Topic name already exists.
The question is what is the reason, calling method results like this?
def form_name_view(request):
if request.method == "POST":
form = FormName(request.POST)
if form.is_valid():
form.save(commit=True)
return HttpResponseRedirect('/') # return index(request)
else:
print('INVALID FORM INPUTS')
else:
form = FormName()
return render(request, 'first_app/form_page.html', {'form': form})
use this
I have a very simple index page view, from which the user can fill in a login popup, which sends a post request to /login
def index(request):
"""Shows list of studyspaces, along with corresponding 'busyness' score"""
context = {'study_space_list': StudySpace.objects.order_by('-avg_rating')}
if request.user.is_authenticated():
context['user'] = request.user
else:
context['login_form'] = LoginForm()
context['user_form'] = UserForm()
context['student_form'] = StudentForm()
return render(request, 'spacefinder/index.html', context)
If the login is valid it simply redirects to the index page, this works fine.
The login view looks as follows:
def user_login(request):
form = LoginForm(request.POST)
if request.method == 'POST' and form.is_valid():
user = form.login(request)
if user:
login(request, user)
return redirect(reverse('spacefinder:index'))
# Load the context all over again
context = {
'study_space_list': StudySpace.objects.order_by('-avg_rating')
}
context['login_form'] = form
context['user_form'] = UserForm()
context['student_form'] = StudentForm()
return render(request, 'spacefinder/index.html', context)
However when the login is incorrect I want to be able to refresh the page and show the login form errors inside the index template (in the login popup)
I'm actually able to achieve this with the above code, but I'm unhappy with the solution for the following reasons:
I have to manually fetch the context all over again, e.g user/student forms and studyspaces, this goes against the DRY principle
When the page is refreshed the url is localhost:8000/spacefinder/login
Screenshot of behaviour here
I'm wondering if there's somehow a way to use redirect to reload the index page and somehow pass errors from my login_form, e.g. something like:
return redirect('spacefinder:index', {'login_form': form})
I've looked into using messages to pass form validation errors, but struggled to get this working since Validation Errors are thrown inside forms.py, and I'm unable to fetch the request instance from inside a ModalForm to properly create a message
You are doing it the wrong way around.
Consider these prerequisites:
entry point to your page is the index view
the index view must only be accessible by authenticated users
the login view allows both methods GET and POST and is accessible to anonymous users only
The reason to use Django is to make use of all the features that it offers, and that includes handling of the above (because that is what most pages need, not only you).
To set it up correctly you need to define your urls.py like this:
from django.contrib.auth.decorators import login_required
urlpatterns = [
....
url('^login/$', user_login, 'login'),
url('^/$', login_required(index), 'index'),
....
]
In your settings/base.py (or settings.py if you have no environment differentiation) tell Django how to redirect users:
LOGIN_URL = reverse_lazy('login')
LOGIN_REDIRECT_URL = reverse_lazy('index')
https://docs.djangoproject.com/en/1.9/ref/settings/#login-url
https://docs.djangoproject.com/en/1.9/ref/settings/#login-redirect-url
Simplify your index view:
def index(request):
"""Shows list of studyspaces, along with corresponding 'busyness' score"""
context = {'study_space_list': StudySpace.objects.order_by('-avg_rating')}
if request.user.is_authenticated():
context['user'] = request.user
else:
return HttpResponseForbidden() # prevented by Django, should never happen
return render(request, 'spacefinder/index.html', context)
Let the user_login view deliver the empty login form:
#require_http_methods(["GET", "POST"])
def user_login(request):
params = getattr(request, request.method)
form = LoginForm(params)
if request.method == 'POST' and form.is_valid():
user = form.login(request)
if user:
login(request, user)
return redirect(reverse('spacefinder:index'))
# Load the context for new form or form with errors
context = {
'study_space_list': StudySpace.objects.order_by('-avg_rating')
}
context['login_form'] = form
context['user_form'] = UserForm()
context['student_form'] = StudentForm()
return render(request, 'spacefinder/index.html', context)
You have not presented any code that handles the UserForm or the StudendForm. You would need to add that to the user_login view, as well - if this is something that all users should fill in every time they login. Otherwise use a different view.
It's worth looking at modules like allauth. They might spare you some work when it comes to allowing users to login with their e-mail addresses, ascertain that e-mail addresses are unique in the system etc.
I want to show same data to user as posted by him using form after saving it in database.
I am not getting the logic for it.
I am trying to do something like this:
def CreateDeal(request):
if request.method == "POST":
form = DealForm(request.POST)
if form.is_valid():
form.save(commit = True)
data = form.data
return render(request, '/path_to/deal_detail.html',data=data)
Is it ok ?
Is there any better way to do it?
If you do it this way, a redirect of the "detail" page will resubmit the form. This is generally not desired behaviour.
A better way would be to create a detail view for you saved object (if you haven't already) and redirect the user to the detail view of that particular object:
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
def CreateDeal(request):
if request.method == "POST":
form = DealForm(request.POST)
if form.is_valid():
obj = form.save(commit=True)
return HttpResponseRedirect(reverse('deal-detail-view', args=(obj.id,)))
# or return HttpResponseRedirect(obj.get_absolute_url())
# if `get_absolute_url` is defined