I want to send a basic form to views. I create everything that it need but when I submit the post, it doesn't send a return a blank page.
This is my form and app:reports is the same page with form, because I want to return the same page. I need the values of year_one and year_two.
<form method="post" action="{% url 'app:reports' %}">
{% csrf_token %}
<label for="year_one">Select year 1:</label>
<select id="year_one" name="year_one">
{% for case in query_trend %}
<option value="{{case.date_created__year}}" >{{case.date_created__year}}</option>
{% endfor %}
</select>
<label for="year_two">Select year 2:</label>
<select id="year_two" name="year_two">
{% for case in query_trend %}
<option value="{{case.date_created__year}}">{{case.date_created__year}}</option>
{% endfor %}
</select>
<button onclick="test()">click</button>
</form>
And this is my view
if self.request.method == 'POST':
year_one = self.request.GET.get('year_one')
year_two = self.request.GET.get('year_two')
return HttpResponseRedirect('fdm:outstanding_reports')
What should I do for using these values in views?
Assuming your button's test() method is successfully submitting the form...If you are passing the request to your view,ie,
def reports(request):
Then you can refer to the posted values of year_one and year_two as:
if request.method == 'POST':
year_one = request.POST.get('year_one')
year_two = request.POST.get('year_two')
(GET is when you send values contained in the URL, eg page?year_1=1975&year_2=1300, POST is when it happens in the background. A form will generally use only one or the other, so you your version probably wasn't getting any values. Confusingly, you also use the lowercase '.get()' to retrieve the POST values)
Related
I have a problem with trying to get a response from my HTML page using Django (admin).
I have a pretty simple div = contenteditable and need to pass data from this div back after the submit button was clicked.
Everything, including choosing selection and opening the intermediate page works fine. But when I tapped submit button, the condition if "apply" in request.POST failed to work.
Please, tell me, what I'm doing wrong?
This is my Django admin:
class QuestionAdmin(AnnotatesDisplayAdminMixin, admin.ModelAdmin):
def matched_skills(self, question):
return ', '.join(s.name for s in question.skills.all())
def update_skills(self, request, queryset):
if 'apply' in request.POST:
print("something")
skills = []
for question in queryset:
skills.append(self.matched_skills(question))
return render(request,
'admin/order_intermediate.html',
context={'skills': skills})
update_skills.short_description = "Update skills"
This is my order_intermediate.html page:
{% extends "admin/base_site.html" %}
{% block content %}
<form method="post">
{% csrf_token %}
<h1>Adjust skills. </h1>
{% for skill in skills %}
<div>
<div id="title" style="margin-left: 5px" contenteditable="true" > {{ skill }} </div>
</div>
{% endfor %}
<input type="hidden" name="action" value="update_status" />
<input type="submit" name="apply" value="Update skills"/>
</form>
{% endblock %}
Actually, request.POST is an HttpRequest object. For getting available keys in the body of the request, you need to use "request.POST.keys()" method. So, you can simply change your condition to:
if 'apply' in request.POST.keys():
print("something")
In my knowledge, you can not send div content with form submit. However you can use input tag with array in name attribute for this. This will send an array as post variable when submit
First, send skills as a enumerate object from your views
return render(request, 'admin/order_intermediate.html', context={'skills': enumerate(skills)})
Then edit your html to this (Note: if you have css in title id, change it to title class)
{% for i,skill in skills %}
<div>
<input class="title" name="skill[{{ i }}]" value="{{ skill }}" style="margin-left: 5px">
</div>
{% endfor %}
and handle array with any action you want to perform in update_skills()
for skill in request.POST.getlist('skill[]'):
# your code
I am trying to update my foem, and I have Country value in dropdown and I want to get this value in request, so that i can update my form using this value in request, Please check my code and let me know where I am mistaking.
Here is my test.html file...
<select name='country'>
<option>Select One</option>
{% for countries in country %}
<option value="{{country.id}}" {% if countries.id == datas.country_id %}selected{% endif
%}>{{countries.country}}</option>
{% endfor %}
</select>
here is my views.py file...
datas = MyModelName.objects.get(pk=id)
if request.method == "POST"
datas.country = request.POST.get('country')
datas.save()
it's not selecting the country, it's giving me error, Please guide me how i can solve this issue.
you better use ModelForm to edit data in your models, it allows you to check all entered values in more clean way
create ModelForm to edit your data
class MyModelNameEditForm(forms.ModelForm):
class Meta:
model = MyModelName
then in your views.py you can do this:
datas = MyModelName.objects.get(pk=id)
if request.POST:
edit_form = MyModelNameEditForm(request.POST, instance=datas)
if edit_form.is_valid():
edit_form.check()
else:
edit_form = MyModelNameEditForm(instance=datas)
# don't forget to send your form as a parameter to your template
return render(request, "path_to_template/test.html", {'edit_form': edit_form})
then in your test.html you can replace:
<select name='country'>
<option>Select One</option>
{% for countries in country %}
<option value="{{country.id}}" {% if countries.id == datas.country_id %}selected{% endif
%}>{{countries.country}}</option>
{% endfor %}
</select>
with one line
{{ edit_form.country }}
you can read more about ModelForm in official docs https://docs.djangoproject.com/en/3.1/topics/forms/modelforms/#modelform
My Goal
I have a django project with a form, and I want to display a preview page before the user submits.
The problem
I can display a preview page using a Django FormPreview, but not all form data is displayed properly. Specifically, if I have a field with choices, the string values of these choices aren't displayed. I'm also having problems applying template filters to date fields. The end result is that some data on the preview page is visible but other data is blank:
However, if I display the same data for posts that have actually been submitted, then everything displays properly:
My Code
models.py:
class Game(models.Model):
# Game Choices
FOOTBALL = 0
BASKETBALL = 1
TENNIS = 2
OTHER = 3
GAME_CHOICES = (
(FOOTBALL, 'Football'),
(BASKETBALL, 'Basketball'),
(TENNIS, 'Tennis'),
(OTHER, 'Other')
)
game_id = models.AutoField(primary_key=True)
location = models.CharField(max_length=200, verbose_name="Location")
game = models.IntegerField(choices=GAME_CHOICES, default=FOOTBALL)
game_date = models.DateField(verbose_name='Game Date')
forms.py
class GameForm(ModelForm):
class Meta:
model = Game
fields = (
'location',
'game',
'game_date'
)
I'm pretty sure that the problem is in my views.py: I'm not sure that I'm processing the POST request the right way to feed all data to the preview page.
views.py
def form_upload(request):
if request.method == 'GET':
form = GameForm()
else:
# A POST request: Handle Form Upload
form = GameForm(request.POST) # Bind data from request.POST into a GameForm
# If data is valid, proceeds to create a new game and redirect the user
if form.is_valid():
game = form.save()
return render(request, 'games/success.html', {})
return render(request, 'games/form_upload.html', {
'form': form,
})
preview.py
class GameFormPreview(FormPreview):
form_template = 'games/form_upload.html'
preview_template = 'games/preview.html'
def done(self, request, cleaned_data):
# Do something with the cleaned_data, then redirect
# to a "success" page.
return HttpResponseRedirect('/games/success')
form_upload.html
...
<form method="post">
{% csrf_token %}
<ul><li>{{ form.as_p }}</li></ul>
<button type="submit">Preview your post</button>
</form>
...
preview.html
{% load humanize %}
...
<h1>Preview your submission</h1>
<div>
<p>Location: {{ form.data.location }}</p>
<p>Game Date: {{ form.data.game_date|date:"l, F d, Y" }}</p>
<p>Game Type: {{ form.data.get_game_display }}</p>
</div>
<div>
<form action="{% url 'form_upload' %}" method="post">
{% csrf_token %}
{% for field in form %}
{{ field.as_hidden }}
{% endfor %}
<input type="hidden" name="{{ stage_field }}" value="2" />
<input type="hidden" name="{{ hash_field }}" value="{{ hash_value }}" />
<!-- Submit button -->
<button type="submit">Submit your post</button>
<!-- Go back button -->
<button type="submit">
<a href="{% url 'form_upload' %}"
onClick="history.go(-1);return false;" >
Go back and edit your post
</a>
</button>
</div>
</form>
</div>
...
Two issues
Essentially, I'm having these two issues:
String values for choices are not displayed. If I use the get_FOO_display() method in my preview.html template, it returns blank. However, if I use this in a page after the post has been submitted, it displays properly.
The humanize date filter doesn't work. If I apply a humanize filter ({{ form.data.game_date|date:"l, F d, Y" }}) in preview.html, it also displays blank. Again, this works for submitted posts.
My question essentially is: what's the right way to use the FormPreview here?
form.data does not have get_FOO_display attributes. When you access {{ form.data.get_game_display }} in the template, it fails silently and doesn't display anything.
The get_FOO_display are methods of the instance, so try this instead.
{{ form.instance.get_game_display }}
Wherever possible you should access data from form.cleaned_data (which is validated and 'cleaned') instead of form.data, which is the raw data submitted to the form.
The filters don't work with form.data.game_date because it's a raw string. They should work with form.cleaned_data.game_date, which has been converted to a python date object.
Finally, you haven't implemented anything in your done method, you've just copied the comment from the docs. You could create a new game using cleaned_data as follows:
def done(self, request, cleaned_data):
game = Game.objects.create(**cleaned_data)
return HttpResponseRedirect('/games/success')
I am new with django and I try update some data passing the id_provider from form1 to form2
The form2 have to display the data of the provider
I have an html page with a little form(form1):
Is a a simple input text where the user write a number.
the number is passed to other form as an argument.
My forms.py:
class ConfigForm(forms.ModelForm):
def __init__(self,idprov,*args,**kwargs):
super(ConfigForm,self).__init__(*args,**kwargs)
self.id_provider = idprov
class Meta:
model = Config
And my views.py:
#csrf_exempt
def configView(request):
prov = get_object_or_404(Config, id_proveedor=id)
if request.method == 'POST':
form = ConfigForm(request.post, instance=prov)
if form.is_valid():
form.save()
return HttpResponseRedirect('/monitor/')
else:
form = ConfigForm(Config.id_proveedor,instance=prov)
return render_to_response('config.html',{'form':form},RequestContext(request))
This is the form(form2) where I try to display the data:
{% block content %}
<div class="container">
<div class="row">
<div class="col-md-4">
<form method='POST' action='' class='form'>
<div class="form-group">
{% csrf_token %}
{{ form.as_p }}
</div>
<button type='submit' class="btn btn-primary">Grabar</button>
</form>
</div>
</div>
</div>
{% endblock %}
I receive the error:
TypeError at /config/
id() takes exactly one argument (0 given)
I don't know if my error are in the method of the form where I try to update the data (form2) or I have some error in the view of the form.
I think I am not getting the value of the input text int the right way.
Any advice, link or snippet will be very helpful
Thanks in advance
id is a Python function and you didn't create it
>>> id('test')
35092128
Try
#csrf_exempt
def configView(request):
# Get your ID in another way for example this one
pk = request.POST.get('id', None)
if pk is None:
# Handle error
prov = get_object_or_404(Config, id_proveedor=pk)
# ^^
should works
BTW using csrf_exempt is generally not a good idea.
I'm trying to get file uploads with flask-uploads working and running in to some snags. I'll show you my flask view function, the html and hopefully someone can point out what I'm missing.
Basically what happens is that I submit the form and it fails the if request.method == 'POST' and form.validate(): check in the view function. It jumps down to display the template. wtforms isn't kicking me any errors on the form so I'm wondering why its failing that if statement.
What am I over looking?
Setting up flask-uploads:
# Flask-Uploads
photos = UploadSet('photos', IMAGES)
configure_uploads(app, (photos))
View:
def backend_uploadphoto():
from Application import photos
from Application.forms.backend import AddPhotoForm
clients = Client.query.all()
events = Event.query.order_by('date').all()
form = AddPhotoForm(request.form, csrf_enabled=True)
if request.method == 'POST' and form.validate():
from uuid import uuid4
uuid = uuid4()
filename = '{0}.jpg'.format(uuid)
photo = Photo(uid=uuid, client=request.form['client'], event=request.form['event'])
photofile = photos.save(request.files.get('photo'), photo.filename)
return redirect(url_for('backend'))
return render_template('backend/addphoto.html', form=form, clients=clients, events=events)
Form:
class AddPhotoForm(Form):
photo = FileField('Photo')
client = IntegerField('Client:')
event = IntegerField('Event:')
HTML:
<form action="{{url_for('backend_uploadphoto')}}" method="post">
<p>
{{form.client.label}}
<select name="client">
{% for client in clients %}
<option value="{{client.id}}">{{client.fullname}}</option>
{% endfor %}
</select>
{{form.client.errors}}
</p>
<p>
{{form.event.label}}
<select name="event">
{% for event in events %}
<option value="{{event.id}}">{{event.name}}</option>
{% endfor %}
</select>
{{form.event.errors}}
</p>
<p><label for="photo">Photo:</label>{{form.photo}} <input type="submit" value="Upload"> {{form.photo.errors}}</p>
</form>
You have csrf_enabled=True but your form doesn't have any CSRF protection since you aren't inheriting from SecureForm. If you want to enable CSRF, read the documentation and update your form definition.
If this was unintended, you can remove csrf_enabled=True and your logic will work as expected.
To enable CSRF protection, there are a few steps:
Inherit from SecureForm
Create the generate_csrf_token and validate_csrf_token methods in your form. These methods will generate a unique key and raise errors when it doesn't validate.
Add {{ form.csrf_token }} to your template.