I have a list of multiple objects from my database (named "plp's"), arranged in a table. Next to each "plp" element I have a button "Edit" to modify that particular entry.
Next, I redirect the user to a new url, where I pass the id of that "plp", and show the form to edit it, with a "save" button.
After pressing the "save", which is request.POST, I want to redirect the user back to the first url, with the list of all the "plp" objects in one list. That means to the site, where he first pressed "Edit".
Can I somehow save the url of where the "Edit" was clicked, and pass it to my views.py?
Thank you
listdns.html:
<td>
Uredi
</td>
urls.py:
rl(r'^(?P<plp_id>\d+)/uredi$', plp_list_uredi,name="plpuredi")
views.py:
def plp_list_uredi(request, plp_id=None):
moj_plp=PLPPostavka.objects.get(id=plp_id)
form=PLPPostavkaForm(request.POST or None,request=request,dns=moj_plp.dns, instance=moj_plp)
context ={
'plp':moj_plp,
'form':form,
}
if request.POST:
if form.is_valid():
plp = form.save()
return redirect(request.path)
return render(request, "plp_pos/uredi.html",context)
uredi.html
<form action="" method="POST">
{% csrf_token %}
<div class="box">
<div class="box-header">
<h4 class="box-title">
Urejanje PLP Postavke
</h4>
</div>
<div class="box-body">
{% for field in form %}
<div class="form-group">
<label for="{{ field.id_for_label }}" class="col-md-2 control-label detail">{{ field.label }}</label>
<div class="col-md-10">
{% if field|field_type == "datefield" %}
{% render_field field class+="form-control dateinput" %}
{% else %}
{% render_field field class+="form-control" %}
{% endif %}
</div>
</div>
{% endfor %}
</div>
<div class="box-footer">
<div class="box-tools pull-right">
<input type="submit" value="Shrani" class="btn btn-primary" />
</div>
</div>
Don't you only have 1 page to edit all the elements? Then you could perhaps hardcode the link e.g.
return HttpResponseRedirect(my_edit_url)
If this doesn't work and you need to go 2 pages back take a look at this post:
How to redirect to previous page in Django after POST request
Related
I have a contact page with a simple form.
Here is views.py:
def contact_view(request):
if request.method == 'GET':
form = ContactForm()
else:
form = ContactForm(request.POST)
if form.is_valid():
subject = form.cleaned_data['subject']
from_email = form.cleaned_data['from_email']
message = form.cleaned_data['message']
try:
send_mail(subject, message, from_email, settings.ADMIN_EMAILS)
except BadHeaderError:
return HttpResponse('Invalid header found.')
return redirect('success')
return render(request, "base/contact.html", {'form': form})
def success_view(request):
return HttpResponse('Success! Thank you for your message.')
this is contact.html:
{% block content%}
<main class="page contact-page">
<section class="portfolio-block contact">
<div class="container">
<div class="heading">
<h2>Contact me</h2>
</div>
<form method="post">
{% csrf_token %}
<div class="mb-3"><label class="form-label" for="name">Your Name</label><input class="form-control item" type="text" id="name"></div>
<div class="mb-3"><label class="form-label" for="subject">Subject</label><input class="form-control item" type="text" id="subject"></div>
<div class="mb-3"><label class="form-label" for="email">Email</label><input class="form-control item" type="email" id="email"></div>
<div class="mb-3"><label class="form-label" for="message">Message</label><textarea class="form-control item" id="message"></textarea></div>
<div class="mb-3"><button class="btn btn-primary btn-lg d-block w-100" type="submit" value="submit">Submit Form</button></div>
</form>
</div>
</section>
</main>
{% endblock %}
When I use form.as_p it works very well but when I use this template it is not working
it only shows in the terminal that a post request was made.
The html looping syntax of form is following, where we have access to specific field, field.label ,non_field_errors as well as particular field errors.
In your case you can use in this way:
contact.html
{% block content%}
<main class="page contact-page">
<section class="portfolio-block contact">
<div class="container">
<div class="heading">
<h2>Contact me</h2>
</div>
<form method="POST" novalidate>
{% csrf_token %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
<div>
{{error}}
</div>
{% endfor %}
{% endif %}
{% for field in form %}
<p>{{field.label_tag}} {{field}}</p>
<br>
{% for error in field.errors %}
<span>{{error}}</span>
{% endfor %}
{% endfor %}
<input type="submit" value="Save">
</form>
</div>
</section>
</main>
{% endblock %}
You can use it as above it will work perfectly with your existing views, as you said it is working with form.as_p.
If you give only form.as_p, it will render form fields in <p> tag of html, you can see through Ctrl+U of view page source,there we cannot have more control over form.
Your question -- How can i use bootstrap's classes in django's form?
Answer - You can set through widget in your form's fileds. for example:
class MyForm(forms.Form):
name=forms.CharField(widget=forms.TextInput(attrs={'class':'form-control'}))
In the above way, you can set it to every field.
How to make it such that if there are errors in the form, all the data I have keyed into the field remains and the error shows for me to edit what I need to edit.
Because it is very user-unfriendly if people press submit, and everything they have previously typed has to be retyped again due to an error that caused them to need to submit the form again.
just like when we post a stackoverflow question, if there are errors in our question eg time limit, whatever we have typed previously remains
Let me know if you require more code.
html
<form class="create-form" method="post" enctype="multipart/form-data">{% csrf_token %}
<div class="form-group">
<label for="id_title">Title</label>
<input class="form-control" type="text" name="title" id="id_title" placeholder="Title" required autofocus>
</div>
<button class="submit-button btn btn-lg btn-primary btn-block" type="submit">Submit</button>
</form>
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<div class="alert alert-danger">
<strong>{{ error|escape }}</strong>
</div>
{% endfor %}
{% endif %}
views.py
def create_blog_view(request):
context = {}
user = request.user
if request.method == 'POST':
form = CreateBlogPostForm(request.POST or None, request.FILES or None)
if form.is_valid():
obj.save()
return redirect('HomeFeed:main')
else:
context['form'] = form
return render(request, "HomeFeed/create_blog.html", context)
You are rendering the fields manually by writing the tags. When you render using the form instance Django automatically sets the value attributes with the previous values. You can use {{ form.as_table }}, {{ form.as_p }}, {{ form.as_ul }}. You can also render fields individually using {{ form.title }} where title is the field name.
I am working on app in django 1.11, on search feature. I installed elasticsearch - here all things are working.
In base.html and under url 127.0.0.1:8000 - I have form to search and I would like to keep this form here. On another hand I have search app with view, url, template - under url 127.0.0.1:8000/search/ - search is working here.
To solve this problem - search on main page and redirect on site with results I was trying to use action attribute in django form.
form in base.html
<form action="{% url 'search:search' %}" method="post">
{% csrf_token %}
<div class="input-group">
<input type="text" class="form-control" id="q" {% if request.GET.q %}value="{{ request.GET.q }}"{% endif %} name="q" placeholder="Search">
<div class="input-group-append">
<button class="btn btn-outline-primary" type="button">GO</button>
</div>
</div>
</form>
view in search app
def search(request):
q = request.GET.get('q')
if q:
posts = PostDocument.search().query('match', title=q)
else:
posts = ''
return render(request, 'search/search.html', {'posts': posts})
template with results
{% extends 'base.html' %}
{% block content %}
{% for p in posts %}
{{ p.title }}
{% endfor %}
{% endblock content %}
{% block sidebar %}{% endblock sidebar %}
You here mix up GET and POST. If the method is method="post", then the data is passed in the request, and thus ends up in the request.POST query dictionary.
If on the other hand the method is method="get", then the data ends up in the querystring of the URL. In that case, you can indeed use request.GET.
Often (not always), search queries are done with querystrings, since then a person can copy the URL and send it to another person, and that person thus can see the search results.
You can thus change the form to:
<form action="{% url 'search:search' %}" method="get">
{% csrf_token %}
<div class="input-group">
<input type="text" class="form-control" id="q" {% if request.GET.q %}value="{{ request.GET.q }}"{% endif %} name="q" placeholder="Search">
<div class="input-group-append">
<button class="btn btn-outline-primary" type="button">GO</button>
</div>
</div>
</form>
When I render the form in HTML, I use this view. the patient_id is used to denote what patient the check in is for and for name display and such.
def Checkin(request, patient_id):
patient = get_object_or_404(PatientInfo, pk=patient_id)
form = forms.PatientCheckinForm()
return render(request, 'patientRecords/checkin.html', {'patient': patient, 'form':form})
When I submit the patient form filled out as a POST method, I still need access to the patient_id. Currently this is the view that accepts the filled form:
def CheckinSubmit(request):
if request.method == 'POST':
form = forms.PatientCheckinForm(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.date_time_of_checkin = dt.now()
instance.patient = patient.patient_id
instance.save()
return redirect('patientRecords/index.html')
I want to set the instance.patient to the patient_id that was part of patient from the Checkin view. Is there a way to pass the patient data back along with the POST method or is there another way this can be done?
For reference, here is my template and I am using ModelForm not form.
{% block content %}
<div class="container">
<h1>Patient Checkin</h1>
<h2>{{patient.first_name}} {{patient.last_name}}</h2>
</div>
<div class="container">
<form action="{% url 'patientRecords:checkinsubmit' %}" method="POST" class="form">
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Submit</button>
{% endbuttons %}
</form>
</div>
{% endblock %}
Thanks in advance!
You should be able to simply add a hidden input to your form to capture the patient ID:
{% block content %}
<div class="container">
<h1>Patient Checkin</h1>
<h2>{{patient.first_name}} {{patient.last_name}}</h2>
</div>
<div class="container">
<form action="{% url 'patientRecords:checkinsubmit' %}" method="POST" class="form">
<input type="hidden" name="patient_id" value="{{patient.patient_id}}" />
{% csrf_token %}
{% bootstrap_form form %}
{% buttons %}
<button type="submit" class="btn btn-primary">Submit</button>
{% endbuttons %}
</form>
</div>
{% endblock %}
(Note this assumes that the patient ID is accessible from the patient_id property of the patient object.)
Then, in your CheckinSubmit method, you can access this value via request.POST.get('patient_id')
Alternatively, it appears that your check in form loads with the patient ID in the URL. In your CheckinSubmit method, you should be able to access this URL through the request.META.HTTP_REFERER property. You could then parse the URL (e.g., using request.META.HTTP_REFERER.split('/')[len(request.META.HTTP_REFERER.split('/')) - 1] to pull out the patient ID.
Example
<form method="post" action = "{% url 'user_search_from_group' %}">
<div class="module-option clearfix">
<div class="input-append pull-left">
<input type="hidden" name="groupname" value="{{ gpname }}" />
{% csrf_token %}
<input type="text" class="span3" placeholder="Filter by name" id="username3" name="username3" required>
<button type="submit" class="btn" name="submit">
<i class="icon-search"></i>
</button>
</div>
</div>
</form>
Here a hidden field is used to pass a value along form.
def user_search_from_group(request):
if request.method == 'POST':
username3 = request.POST.get('username3')
gname = request.POST.get('groupname')
Using request we are use the value inside view
I've been working to make an edit form where shows data saved in db and user can edit it like jsp model and view. When user click button it shows add form but all the relevant information in db is already filled up in the form, so user can modifying old data and once they click submit button it redirect to main.
I succeeded to display a form when user click edit button but failed to get data.
this is views.py
#login_required
def update_article(request, article_no):
article = get_object_or_404(Article, no=article_no)
if request.method == "POST":
form = ArticleForm(request.POST, instance=article)
if form.is_valid():
post = form.save(commit=False)
post.save()
return redirect('blog.views.detail', no=article.no)
else:
form = ArticleForm(instance=article)
return render(request, 'blog/update_article.html', {'form': form})
urls.py
url(r'^update_article/(?P<article_no>[0-9]+)/$', views.update_article, name='update_article'),
update_article.html
{% extends 'blog/base.html' %}
{% block body %}
<form class="form-horizontal" role="form" action="create_article.html" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'blog/form_template.html' %}
<button type="submit" class="button-primary">submit</button>
</form>
list
{% endblock %}
detail.html
This is part of the page send users to update_article.html
<form action="{% url 'blog:update_article' item.no %}" method="post" style="display: inline;">
{% csrf_token %}
<input type="hidden" name="no" value="{{ item.no }}" />
<button type="submit" class="button-primary">edit</button>
</form>
form_template.html
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }}</span>
</div>
<label class="control-label col-sm-2" for="title">{{ field.label_tag }</label>
<div class="col-sm-10">{{ field }}</div>
</div>
{% endfor %}
In update_article views
pass article object with form
return render(request, 'blog/update_article.html', {'form': form, 'article': article})
and then form in html page
<form class="form-horizontal" role="form" action="create_article.html" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% include 'blog/form_template.html' %}
<input class="u-full-width" type="text" name="title" value="{{article.title}}"/>
<textarea class="u-full-width" name="content" value="{{article.content}}"></textarea>
<button type="submit" class="button-primary">등록</button>
</form>
I think this would help your problem
also I guess your action link is not valid