Django - how to show all formset value on the page - django

I have the form that looks like this:
class ItemForm(forms.Form):
item = forms.IntegerField()
And this is view for my form:
def testform(request):
item_form = formset_factory(ItemForm, extra=2)
if request.method == 'POST':
item_formset = item_form(request.POST, prefix='items')
if item_formset.is_valid():
for items in item_formset:
cd = items.cleaned_data
item = cd.get('item')
return render(request, 'testform/result.html', {'item_formset':item_formset})
else:
item_formset = item_form(prefix='items')
return render(request, 'testform/index.html', {'item_formset':item_formset})
Here is my result.html:
{% for i in cd %}
{{item}}
{% endfor%}
On result.html page i want to show all values of item formset that input on form page. But I've got just clean page.
What i'm doing wrong. Thanks for your help

You need to iterate over your formset, which you're passing to your render method as 'item_formset'. So your result.html should look like:
{% for item_form in item_formset %}
{{ item_form.item }}
{% endfor %}
Notice you'll be accessing the item field on each formset form, just as you would in a normal form.

You can iterate over each element in form set or display the entire formset at a time. You can find it here: https://docs.djangoproject.com/en/1.7/topics/forms/formsets/#understanding-the-managementform

Related

Check the form input value to existing value in Django

In in my database there are some emails those should be checked with the form value which is entered in email field
models.py
class Friend(models.Model):
email = models.EmailField(max_length=100)
forms.py
class FriendForm(forms.ModelForm):
class Meta:
model = Friend
fields = ['email']
views.py
def check(request):
if request.method == "POST":
form = FriendForm(request.POST)
if form.is_valid():
queryset = Friend.objects.all
return render(request,"two.html",{"queryset":queryset})
else:
form = FriendForm()
return render(request, 'emaill.html', {'form': form})
emaill.html
<body>
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" name="Submit">
</form>
</body>
two.html
<body>
<h1>found</h1>
{% for obj in queryset %}
{{obj.email}} </br>
{% endfor %}
</body>
when user submited any email that should be checked with models email that means with existing one if matches in should render to two.html it should show connect
if mail does not match with mail that is in database it should show no such mail
Okay, I understand what you are trying to do. You are doing an email search.
def check(request):
if request.method == "POST":
form = FriendForm(request.POST)
if form.is_valid():
email = form.cleaned_data("email")
try:
friend = Friend.objects.get(email=email)
return render(request,"email1.html",
{"friend":friend})
except Friend.DoesNotExist:
return render(request, "email1.html", {"form":form})
If you are interested in connecting them, then you should use the get method of the ModelManager (objects). That will return a single object if it exists.
In your template. As you can see I have saved some typing on an extra template by using conditions in the template.
{% if form %}
#display your form
{% else %}
#display the friend as you want
{% endif %}
I recommend you go slow and do more reading of the documentation. I am here. Note that I changed your queryset to friend. queryset is misleading as it points that you want multiple objects. So in your template you cant iterate, instead you display friend without iterating.
{{ friend }}

Django form with multiple checkboxes

I am really new to Django! I have a page that displays items with checkboxes next to them. The number of items/checkboxes varies. When a button is pressed, I want the corresponding checked item to be modified.
So far, I have tried to wrap it all in one form:
<form method="post">
{% csrf_token %}
{% for event in items %}
{{ event.eventID }}
<input type="checkbox" value="{{ event.eventID }}" name="choices">
{% endfor %}
<button type="submit">Approve</button>
</form>
I want to collect them in a Django form field. I am trying to use ModelMultipleChoiceField:
class ApproveEventForm(forms.Form):
choices = forms.ModelMultipleChoiceField(queryset = Event.objects.all(), widget=forms.CheckboxSelectMultiple())
And in my views, I want to edit the selected items:
def approve_event(request):
if request.method == "POST":
form = ApproveEventForm(request.POST)
print(form.errors)
if form.is_valid():
for item in form.cleaned_data['choices']:
item.approved = True
item.save()
else:
form = ApproveEventForm()
unapproved = Event.objects.filter(approved=False)
return render(request, 'app/approve_event.html', {'items': unapproved, 'form': form})
My form is not valid and form.errors prints: choices "" is not a valid value for a primary key.
How can I fix this? Or is there another way to access the selected items?
Edit: passed the form to the template.
Managed to fix it using MultipleChoiceField instead of ModelMultipleChoiceField. Then populated the choices with existing event IDs and passed it to the template.
In forms:
choices = forms.MultipleChoiceField(widget = forms.CheckboxSelectMultiple())
In views:
form.fields['choices'].choices = [(x.eventID, "Event ID: " + x.eventID) for x in unapproved]
Had to change some of the logic for finding and editing Event objects too.

Edit a Key/Value Parameters list Formset

I'm looking for a convenient solution to create an 'edit settings' key/values page.
Parameters model :
class Parameter(models.Model):
key = models.CharField(max_length=50)
value = models.CharField(max_length=250)
showInUI = models.SmallIntegerField()
Initial Keys/Values are already inserted in table.
I load them and send them using a model formset factory using these lines :
ParameterFormSet = modelformset_factory(Parameter, extra=0, fields=('key', 'value'))
parameterFormSet = ParameterFormSet(queryset=Parameter.objects.filter(showInUI=1))
return render_to_response('config.html', {'parameterFormSet': parameterFormSet}, context_instance=RequestContext(request))
Template side, when formset is displayed, keys and values are shown as inputs.
I'd like to find a convenient way to display form keys as readonly labels and values as inputs. And, when submited, validate them according django standards.
I've read a lot of stuff, I guess the solution may be a custom widget, but I could find a reliable solution.
Thanks for reading.
EDIT :
Working solution
views.py
def config(request):
ParameterFormSet = modelformset_factory(Parameter, extra=0, fields=('value',))
if request.method == "POST":
try:
formset = ParameterFormSet(request.POST, request.FILES)
except ValidationError:
formset = None
return HttpResponse("ko")
if formset.is_valid():
formset.save()
return HttpResponse("ok")
#ParameterFormSet = modelformset_factory(Parameter, extra=0, fields=('value',))
parameterFormSet = ParameterFormSet(queryset=Parameter.objects.filter(showInUI=1))
return render_to_response('config.html', {'parameterFormSet': parameterFormSet}, context_instance=RequestContext(request))
template
<form method="post">
{% csrf_token %}
{{ parameterFormSet.management_form }}
{% for form in parameterFormSet %}
<div>
{{ form.instance.key }}
{{ form }}
</div>
{% endfor %}
<input type="submit" />
</form>
If you do not want the value to be editable, don't include it in fields when creating the form set.
ParameterFormSet = modelformset_factory(Parameter, extra=0, fields=('value',)) # don't forget the trailing comma after 'value' otherwise it's not a tuple!
In your template, you can then loop through the forms in the form set, and display the key at the same time.
{% for form in parameter_form_set %}
{{ form.instance.key }}{# display the key related to this form #}
{{ form }}{# display the form #}
{% endfor %}

repeated modelform not validating in modelformset - django

I have a ModelForm that users can submit to save information to a database. I want to extend it with a ModelFormset so that the user can view and submit the multiple of the same model forms with different information at the same time. However, my POST data isn't binding to the ModelFormset, so the ModelFormset fails as invalid upon is_valid(). I see there is data associated with request.POST.copy(), it just
views.py
def create(request):
if request.method == 'POST':
post_data = request.POST.copy()
print "POST DATA"
print post_data
for i in post_data:
print i
formSet = WorkOrder_Form(post_data)
print "FORMSET"
print formSet
if formSet.is_valid():
formSet.save()
else:
print 'INVALID'
return HttpResponseRedirect('/Shelling/')
else:
formSet = formset_factory(WorkOrder_Form, extra=1)
return render_to_response('create.html',{'WorkOrder_Form':formSet}, context_instance=RequestContext(request))
template: (create.html)
{% load url from future %}
Return to Index </li>
<br>
<br>
<form action="{% url 'create' %}" method="post"> {% csrf_token %}
{% for WorkOrder in WorkOrder_Form %}
{{ WorkOrder.as_ul }}
<br>
{% endfor %}
You are using model forms, so you should use modelformset_factory instead of formset_factory. You can create the formset class outside of the create view. Then, you need to instantiate the formset in the GET and POST branches of your view.
Putting it together, you have the following (untested, so there might be some typos!)
WorkOrderFormSet = formset_factory(WorkOrder_Form, extra=1)
def create(request):
if request.method == 'POST':
post_data = request.POST.copy()
formset = WorkOrderFormSet(data=post_data, queryset=WorkOrder.objects.none())
if formset.is_valid():
formset.save()
else:
print 'INVALID'
return HttpResponseRedirect('/Shelling/')
else:
formset = WorkOrderFormSet(queryset=WorkOrder.objects.none())
return render_to_response('create.html',{'formset':formset}, context_instance=RequestContext(request))
And in the template:
{% for form in formset %}
{{ form.as_ul }}
{% endfor %}

Two views in a Django page

I'm having problems displaying the input box of my page. On this same page I would like to have two views, one that accesses and retrieves data and the other a form. As it's an event sign-up page, the first view show the details of a specific event and the second is a view to remove a specific user from the event itself.
My views.py
def ShowSpecificEvent(request, eventslug):
if request.method == 'POST':
form = RemovalForm(request.POST)
if form.is_valid():
event = Event.objects.get(slug=eventslug)
context = {'event': event,}
updated_event = event.signed_up.remove(for_removal = form.cleaned_data['for_removal'],)
updated_event.save()
return render_to_response('base_specific_event.html', context, context_instance=RequestContext(request))
event = Event.objects.get(slug=eventslug)
context = {'event': event,}
return render_to_response('base_specific_event.html', context, context_instance=RequestContext(request))
def Remove(request, eventslug):
if request.method == 'POST':
form = RemovalForm(request.POST)
if form.is_valid():
event = Event.objects.get(slug=eventslug)
context = {'event': event,}
updated_event = event.signed_up.remove(for_removal = form.cleaned_data['for_removal'],)
updated_event.save()
return render_to_response('base_specific_event.html', context, context_instance=RequestContext(request))
return HttpResponseRedirect('base_remove_user.html')
My template
{% block content %}
event details...
{% if user.is_authenticated %}
{% if event.sign_up_is_live %}
<p> Sign me up!</p>
<form action='' method='post'>
{% csrf_token %}
{% if form.errors %}<p>Please correct the following fields:</p>{% endif %}
<div class='register_div'>
{% if form.for_removal.errors %} <p class='error'>{{ form.for_removal.errors }}</p>{% endif %}
<p><label for='for_removal'{% if form.for_removal.errors %}class='error'{% endif %}>User to be removed:</label></p>
<p>{{ form.for_removal }}</p>
</div>
<p><input type='submit'></p>
</form>
{% endif %}{% endif %}
{% endblock %}
I've read this which I think is the most relevant but the method prescribed doesn't really help.
I've also thought of splitting up the two pages, but I won't be able to retrieve the eventslug in my remove user page.
Thanks in advance :)
Update:
gutrt's answer was a great help and I've managed to get the input box to appear by changing ShowSpecificEvent to the following:
def ShowSpecificEvent(request, eventslug):
event = Event.objects.get(slug=eventslug)
form = RemovalForm(request.POST or None)
context = {'event': event, 'form': form,}
if request.method == 'POST':
if form.is_valid():
updated_event = event.signed_up.remove(request.POST.get('for_removal'))
updated_event.save()
return HttpResponseRedirect('base_user_removed.html')
else:
return render_to_response('base_specific_event.html', context, context_instance=RequestContext(request))
return render_to_response('base_specific_event.html', context, context_instance=RequestContext(request))
However, after submitting the form, I get a ValueError(invalid literal for int() with base 10: 'a_technicolor_skye') where a_technicolor_skye is the user I'm trying to remove. Does anyone have any ideas? Btw, event.signed_up is a many to many field and I've set it to null=True and blank=True.
You can pass all of the information into the context variable:
context = {'event': event, 'form': my_form}
Then both are available in your template. Note that this means you are going to end up using 1 view but computing all the information for the page in that view or its methods.