I'm learning django and i'm blocked on a template syntax error.
I have this function in my views.py :
def AccountUpdateView(request):
template_name='portal/accountupdate.html'
context = {"forms":UserForm}
return render(request,template_name,context)
There is my template :
<form action="/account/update/" method="POST">
<ul>
{% csrf_token %}
{% for form in forms %}
<li>{{form.label}}
<input type="text" name="{{form.name}}" maxlength="32" required="" id="id_{{form.name}}" value="{{PLEASE HELP ME !!!}}">
</li>
{%endfor%}
</ul>
<input type="submit" value="Metre a jour" />
</form>
Well, i'm trying to get in the "value" of each form on my template by the current registered user known in django by the call {{user}}
And i would to auto place the values of each forms.
I think a solution is to use the form.name (for the example of the case 'username') and in the value call a thing like this :
user.form.username
It doesn't work and i know that i was dream to hope this exotic call don't work...
If any have a solution :)
Thank's you !
You shouldn't do this at all. Django will automatically output the whole field if you ask it.
For a start, use proper names for your objects. Secondly, if you want to prepopulate the form with data from the current user, then do so in the view. Note, you also need to deal with the posted data:
def AccountUpdateView(request):
template_name='portal/accountupdate.html'
if request.method == 'POST':
form = UserForm(request.POST, instance=request.user)
if form.is_valid():
form.save()
return redirect('/')
else:
form = UserForm(instance=request.user)
context = {"form":form}
return render(request,template_name,context)
Now, use the proper values and attributes in the template:
{% for field in form %}
<li>{{ field.label_tag }}
{{ field }}
{{ field.errors }}</li>
{% endfor %}
Related
I have a page where there is a path /tag/name_of_tag and you can see all posts tagged with that tag.
Inside the page, you can also select another tag in a form and go to that tag.
The problem is that instead of going to /tag/searched_tag, it goes to /tag/?search=searched_tag
How can I change it doesn't leave the ?search= part?
urls.py:
url(r'tag/(?P<input_tag>\w+)$', views.tag_view, name='tag'),
views.py:
def tag_view(request, input_tag):
form = TagSearchForm()
if request.method == 'GET':
form = TagSearchForm(request.GET)
if form.is_valid():
input = form.cleaned_data['search']
print(input)
return redirect('fortykwords:tag_view', input)
else:
form = SearchForm()
latest_post_list = Post.objects.filter(tags=input_tag, status__exact="published")
paginator = Paginator(latest_post_list, 3)
page = request.GET.get('page')
posts = paginator.get_page(page)
context = {'latest_post_list': latest_post_list, 'page_tag': input_tag, 'form': form}
return render(request, 'fortykwords/tag.html', context)
forms.py:
class TagSearchForm(forms.Form):
search = tagulous.forms.SingleTagField(
tag_options=tagulous.models.TagOptions(
autocomplete_view='fortykwords:post_tags_autocomplete'
),
label='Tags',
required=True,
help_text=_('Filter by lead tags. You can organize leads by any tag you want.'),
)
tag.html:
{% extends "base_generic.html" %}
{% block content %}
<form action="." method="get">
{{ form }}
<input type="submit" value="Submit" />
</form>
<h3>Posts with the tag {{ page_tag }}</h3>
{% if latest_post_list %}
<ul>
{% for post in latest_post_list %}
<li> {{ post.author }} {{ post.pub_date }}
<br>
{{ post.title }}</li>
{% for tag in post.tags.all %}
{{ tag.name }}
{% endfor %}
{% endfor %}
</ul>
{% else %}
<p>No posts are available.</p>
{% endif %}
{% endblock %}
You need to provide the argument input to redirect method as input_tag=input.
Example:
return redirect('fortykwords:tag_view', input_tag=input)
It's showing as /tag/?search=searched_tag because your form is submitting by GET but never getting to the redirect. It seems is_valid() is returning False.
I've tested a very similar version of your code and don't think it's a bug in tagulous, but would still be interested to know what had gone wrong (I wrote tagulous). Spotted a couple of places you can streamline your code a bit, so try::
def tag_view(request, input_tag):
# Can't see any POSTs in your example, so you can pass the form GET here
# Might also be nice to pass the original tag in so it shows in the form
form = TagSearchForm(request.GET, initial={'search': input_tag})
# The form already has the GET, so you can go straight into the is_valid
if form.is_valid():
input = form.cleaned_data['search']
print('Valid: ', input)
return redirect('fortykwords:tag_view', input)
else:
print('Invalid: ', form.errors, form.non_field_errors)
# You can remove the else for if not GET, which would never be reached
# on to pagination as before
(although fwiw I'd recommend ipdb instead of print)
Hi, I'm trying to develop a simple django app, and I'm having trouble accessing a form's data. I've looked at django's documentation extensively and many questions on here on the same topic but nothing is working. Here's my code inside my view, that is otherwise working:
def post(self, request):
"""Return only the games from the upcoming gameweek"""
form = GWForm(request.POST)
if form.is_valid():
curr_gw = form.cleaned_data['gweek']
args = {'form': form, 'this_gw_fixtures': Game.objects.filter(gweek=curr_gw), 'curr_gw': curr_gw}
return render(request, self.template_name, args)
else:
curr_gw = 17
form = GWForm()
args = {'form': form, 'this_gw_fixtures': Game.objects.filter(gweek=curr_gw), 'curr_gw': curr_gw}
return render(request, self.template_name, args)
And here's the code of my template:
<form action="/predict/" method="post">{% csrf_token %}
<label for="Gameweek">Gameweek: </label>
<input id="gwparam" type="number" value="{{ curr_gw }}" min="17" max="40">
<input type="submit" value="Go">
</form>
{% if this_gw_fixtures %}
<ul>
{% for game in this_gw_fixtures %}
<li>{{ game }}</li>
{% endfor %}
</ul>
{% else %}
<p>No game predictions are available for this gameweek.</p>
{% endif %}
What I'm trying to do is get the input of a choice form and render a list of games that are in the gameweek selected in the form. Minumum 17, max 40. Here's my form code.
class GWForm(forms.Form):
gweek = forms.ChoiceField(required = False, choices=[(x, x) for x in range(17, 40)])
But when I try to grab the gweek from the form, is_valid() returns true, but form.cleaned_data['gweek'] doesn't return any value at all. Any help would be appreciated. Thanks in advance.
forms.py
class GWForm(forms.Form):
gweek = forms.IntegerField(required=False, min_value=17, max_value=40)
template
<form action="/predict/" method="post">{% csrf_token %}
{{ form }}
<input type="submit" value="Go">
</form>
I am getting this error: ValidationError at /screen-many/
[u'ManagementForm data is missing or has been tampered with'] and I think it is due to the folling code in my view...
# e_pk_list is a list of id's that I got from POST
e_students = Student.objects.filter(pk__in=e_pk_list)
my_iterator = iter(e_students) # Each list item will correspond to a form.
SurveyFormset = formset_factory(SurveyForm, extra=len(e_students))
# Is this the tampering that I can't do??
SurveyFormset.form = staticmethod(curry(SurveyForm, item_iterator=my_iterator))
if request.method == 'POST':
survey_formset = SurveyFormset(request.POST)
if survey_formset.is_valid():
for form in survey_formset:
saved = form.save(commit=False)
saved.surveyset = ss
saved.save()
return HttpResponseRedirect('/')
else:
survey_formset = SurveyFormset()
Thanks
EDIT: I guess I should have mentioned that I already have a managementform in my template....
<form action="" method="POST">{% csrf_token %}
{{ survey_formset.management_form }}
{% for form in survey_formset %}
<div class="item">
{% crispy form %}
</div>
{% endfor %}
<input type="submit" value="Submit" class='button' />
</form>
Its seems that you didn't put management_form in your form .
Put this in your html form where your are displaying SurveyFormset
{{ SurveyFormset.management_form }}
A formset has many forms. Django keeps track of number of forms in formset using management form data. You should add management_form in the template too, which should be posted along with other POST data.
So, you should have:
<form method="POST" action=".">
{{survey_formset.management_form}}
{% comment %}Other form fields{% endcomment %}
</form>
I have a formset which i initialize it in view. one of the form's fields is FileField. and I have to show user the name of his/her previous file name. Because i can't initialize FileField, i want to send file names in list. (I mean for example when you have a Charfield, you can initialize it in views and when you render to template, you will see an input filled with that data, but when you have file upload field you can't filled it in views and sends to template). i don't know how i can loop over forms in formset and list at the same time. And the other thing is when i initialize forms in formset and render to template (I mean for example write data['form-0-Team']='team1' but i can't write data['form-0-Team']='a.png' , so when i render to template, i see field named 'Team' is filled (value=team1) and field named 'File' is not filled and the error 'thid field is required' id shown. ) although it's the first time i'm visiting this page and my method isn't POST. (USUALLY form errors are shown when user clicks on submit and in views it checks if request.method == 'POST', then checks if form.is_valid, it return to template and shows errors, but in mine, it shows errors at the first time euser is visiting the page and before he/she posts data).
I wish i could say my problem. can you please guide me solve this? really thanks.
def myFunc(request):
flagFormSet = formset_factory(FlagFileBaseForm)
if request.method == 'POST':
formset = flagFormSet(request.POST, request.FILES)
if formset.is_valid():
# do s.th
else:
data = {
'form-TOTAL_FORMS': 5,
'form-INITIAL_FORMS': u'0',
'form-MAX_NUM_FORMS': u'',
# add initial form data to it
}
list=['a.png', 'b.png', 'c.png', 'd.png' , 'f.png']
formset = flagFormSet(data)
return render_to_response('myPage.html', RequestContext(request, { 'formset': formset, 'list':list}))
and my template:
<form method="post" action="" enctype="multipart/form-data">
{{ formset.management_form }}
{% for form in formset.forms %}
<div class="form">
<div class="form-row Team">
<div>
<label class="required" for="id_Team">Team:</label>
{{ form.Team }}
{{ form.Team.errors }}
</div>
</div>
<div class="form-row File">
<div>
<label class="required" for="id_File">File:</label>
{{ form.File }}
{{ form.File.errors }}
</div>
#here i want show the name of previous file
</div>
</div>
{% endfor %}
</form>
EDIT:
current result (while request is not post, it shows error)
desired result (form without error with file names)
In Django Templates, if you are trying to render a form that has a FileField. You must pass replace
<form method="post" action="">
with
<form method="POST" enctype="multipart/form-data">
https://docs.djangoproject.com/en/dev/ref/forms/api/#binding-uploaded-files-to-a-form
I'm afraid I don't really understand your question, so apologies if this doesn't help..
If your list is arbitary (as it looks from your question), then you could use django's built in forloop counter to construct your file names -
{% for form in formset %}
{{ form }}
<input type="text" name="file_name" value="{% forloop.counter %}.png">
{% endfor %}
Alternatively have a look at python's zip function. You could use it to build an object that includes both the names and the forms and pass that to your template.
now im learning to validate form, "all" is working, im showing the erros of empty fields, but i have 2 questions:
how ill show the value in the filled fields when there are errors in another fields?, like <input ... value= {{ value }} > the problem is that my fields are not html forms fields.
how ill show the error exactly over the empty fields?
how i have this:
form.py
class NuevaDiligenciaForm(forms.Form):
titulo = forms.CharField(max_length=70)
tipo = forms.ChoiceField(choices=TIPO)
vias= forms.TypedChoiceField(widget=forms.RadioSelect(), choices=CHOICES)
view.py
def add(request):
form = NuevaDiligenciaForm()
errors =[]
if request.method =='POST':
if not request.POST.get('titulo',''):
errors.append('Titulo es requerido')
if not request.POST.get('vias',''):
errors.append('Vias es requerido')
#if not errors:
return render_to_response('account/add.html', { 'formulario':form ,'errors':errors},context_instance = RequestContext(request))
template.html
{% if errors %}
<ul>
{% for error in errors %}
<li>{{ error }}</li>
{% endfor %}
</ul>
{% endif %}
{% if message %}
<p style="color: red;">{{ message }}</p>
{% endif %}
<form action='.' method='POST' class="nueva-diligencia">
{{ formulario.as_p }}
<input type="submit" value="Continuar">
</form>
Thanks again :)
You form code looks fine here but your view needs to change to this:
def add(request):
if request.method =='POST':
form = NuevaDiligenciaForm(request.POST)
if form.is_valid():
clean_data = form.cleaned_data
# Now do something with the cleaned data...
else:
form = NuevaDiligenciaForm()
return render_to_response('account/add.html', { 'formulario': form }
and your template should look like this:
{% if message %}
<p style="color: red;">{{ message }}</p>
{% endif %}
<form action='.' method='POST' class="nueva-diligencia">
{{ formulario.as_p }}
<input type="submit" value="Continuar">
</form>
Now what happens is that if there is bad data from the POST, form.is_valid() will fail and the view will return the validated form, which will include errors next to fields that have them. Django takes care of all the error handling for you here! Try it out and let me know if it works as you expect it to.
This is a pretty good resource if you'd like to see how/why this simplified version actually works better: http://www.djangobook.com/en/2.0/chapter07/