django form doesn't work on click submit - django

I'm trying to do a form, with gender choices. The user could choice between male or female.
What I have now in forms.py:
class GenderForm(forms.Form):
demo = DemoData.objects.all()
GENDER_CHOICES = [
('Male', 'Masculino'),
('Female', 'Feminino')]
gender = forms.ModelChoiceField(demo, widget=Select(), required=True)
choices_distlabel = [('', '')] + GENDER_CHOICES
gender.choices = choices_distlabel
in the template:
<form action="" method="post">
{% for field in form_gender %}
{{ field }}
{% endfor %}
<input type="submit" value="Submit" />
</form>
{% if idgender %}
<img src="/age_gender/{{ idgender }}.png" alt="Graph"/>
{% endif %}
the views:
if form_gender.is_valid():
gender = form_gender.cleaned_data['gender']
gender = gender.gender
if gender:
idgender = gender
return render_to_response('age.html', {'form_gender': form_gender, 'idgender': idgender })
the form is done and works, but the problem is when I click on the submit button nothing happen. He is not given me the information

You have to define url where post data will be sent
This will send post data to url /my_app/my_view/
<form action="/my_app/my_view/" method="post">
{% for field in form_gender %}
{{ field }}
{% endfor %}
<input type="submit" value="Submit" />
</form>
This will send post data to current url you are on.
<form action="." method="post">
{% for field in form_gender %}
{{ field }}
{% endfor %}
<input type="submit" value="Submit" />
</form>

I don't understand why you've defined DemoDataForm in both models.py and forms.py, once as a ModelForm and once as a plain form. Because of that, it's impossible to tell from the code you've posted exactly which class you're instantiating.
I would say, drop the version in forms.py, move the one in models.py into forms.py, and use that. But first you'll need to fix a slight bug - instead of:
fields = ('gender')
you need
fields = ('gender',)
because a one-item tuple always needs a comma, otherwise Python will try to iterate through the string.

Related

Django filter for result from checkbox form

I'm begginer of django and i try to implement search engine to look for recipes that contains selected ingredients.
I want to do form with all ingredients_type from my Model and user can select up to 3 of them (checkbox prefered). Then i want to filter recepe that contains them.
I was looking for generic form but never get right result.
Right now i have only a scratch and Im looking for any advice
model.py
class IngredientsType(models.Model):
type = models.CharField(max_length=60, blank=True)
def __str__(self):
return self.type
search.html
{% for ingredients in ingredients_type %}
<input type="checkbox" id="{{ingredients.type}}">
<label for="{{ingredients.type}}">{{ingredients.type}}</label>
{% endfor %}
<form method="POST" action="#">
<button type="submit" name="save" value="save">szukaj</button>
</form>
Do i have to create custom form or there is good way to use some of generic form?
I think what you are on the right path, but there are some mistakes in your code.
search.html
<form method="POST" action="">
{% csrf_token %}
{% for ingredients in ingredients_type %}
<input type="checkbox" id="{{ingredients.type}}" value="1">
<label for="{{ingredients.type}}">{{ingredients.type}}</label>
{% endfor %}
<button type="submit" name="save" value="save">szukaj</button>
</form>
model.py
You might want to use many-to-many relationship to represent to relation between the ingredient types and the recipes.
views.py
Make sure you have the POST handling method to work with your filter query. This should get data from the form.

Displaying an Image in ModelForm

I have the following model:
class Portfolio(models.Model):
id = models.AutoField(primary_key=True)
member = models.ForeignKey(Member, on_delete=models.CASCADE)
image = models.ImageField(upload_to='portraits/', default='/images/some_image.png')
For that I made the ModelForm:
class PortfolioForm(forms.ModelForm):
class Meta:
model = Portfolio
exclude = ['id']
I need many of those in one template so I am creating them in the Following way in my view
def portfolio_form(request, pk):
...
formset = PortfolioFormSet(queryset=Portfolio.objects.filter(pk__in=list_of_ids))
for x in p]
finally in the html I have this:
<form enctype="multipart/form-data" action="{% url 'elec:portfolio_form' pk=id %}" method="POST">{% csrf_token %}
...
{{ formset.management_form }}
{% for form in formset.forms %}
<tr>{% for field in form %}
{% if field.name == 'image' %}
<td><img src="{{field.image.url}}"></td>
{% else %}
<td align="center" valign="middle">{{field}}</td>
{% endif %}
{% endfor %}</tr>
{% endfor %}
<input type="submit" class="btn btn-default" value="Save and Refresh" />
</form>
Now what I expect to see is the image that I am saving into that Model. The if statement is coming back as false but why?. What am I doing wrong? Everywhere I looked it should work like this.
Also I have added the request.FILES in PortfolioForm with that the instance is not called how can I fix that?
OK I found the solution in Stackoverflow since I used some other words to find a solution.
what you need to do in the template instead of :
{<td><img src="{{field.image.url}}"></td>}
is this :
{<td><img src="{{form.instance.image.url}}"></td>}

Django - How to display all items inside a Object

I have a Profile Object which has a many to many reationship with a Hobbies object. A profile is used for creating a User. Each User can also have a load of hobbies that are predefined. What I want to do is let Users pick some hobbies they are interested in. However, I am not sure how to display all these Hobbies and let Users pick them on the actual display. Here is the code:
TYPES = (
("Football", "Football"),
("Cricket", "Cricket"),
("Swimming", "Swimming"),
("Cycling", "Cycling")
)
class Hobby(models.Model):
myfield = MultiSelectField(choices = TYPES)
And the User :
class Profile(models.Model):
email = models.CharField(max_length=200)
hobbies = models.ManyToManyField(Hobby)
And the HTML code I use is here:
<span class="fieldname">Hobbies</span>
{% for hobby in all_hobbies %}
<input type="checkbox" name={{hobby}} value={{hobby}}> {{hobby}}<br>
{% endfor %}
However this only displays
What I want it to display is all the hobbies with the choices, instead of the whole Object. I am not sure how to do this and would appreciate any help.
Try doing something like
<span class="fieldname">Hobbies</span>
{% for hobby in all_hobbies %}
<input type="checkbox" name="{{ hobby.myfield }}" value="{{ hobby.myfield }}"> {{ hobby.myfield }}<br />
{% endfor %}
Under Hobby class, you should add the str method that will display the value of your hobby instead of 'Object'
def __str__(self):
return self.myfield
You can also use __unicode__ instead of __str__ if you are with Python 2.x
Edit:
After I read again your question, I understood that your problem was specifically not having several checkboxes for the multiple choices you have, here is how you can show all the choices, you should pass the hobbies field as a context :
{% for value, text in form.hobbies.field.choices %}
<div class="ui slider checkbox">
<input id="id_hobbies_{{ forloop.counter0 }}" name="{{ form.hobbies.name }}" type="checkbox" value="{{ value }}"{% if value in checked_hobbies %} checked="checked"{% endif %}>
<label>{{ text }}</label>
</div>
{% endfor %}

In django, how to use another model data from function based views

So I have a form that updates a key_instance object with a borrower. Currently my app needs the user to enter the name of the borrower, but I want it to display a dropdown list of data from another model the user model to select from, is there anyway to do this in a class based view? Here are my views.py and my template. What I was thinking is that I would like to use a get_list_or_404 on the user model and display it as a drop down list in the template and use that selection to populate the form field.
I manged to get the dropdown list to display in my template but I'm not sure as to how to save that value in my views.
Does anyone know if this is the right way or if this is doable? Thank you!!
views.py
def submit_key_request(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk=pk)
names = get_list_or_404(Users)
# If this is a POST request then process the Form data
if request.method == 'POST':
# Create a form instance and populate it with data from the request (binding):
form = UpdateKeyForm(request.POST)
# Check if the form is valid:
if form.is_valid():
# process the data in form.cleaned_data as required (here we just write it to the model due_back field)
key_inst.is_requested = True
key_inst.status = 'r'
key_inst.date_requested = datetime.date.today()
key_inst.borrower = form.cleaned_data['borrower']
key_inst.save()
# redirect to a new URL:
return HttpResponseRedirect(reverse('all-available-keys') )
# If this is a GET (or any other method) create the default form.
else:
form = UpdateKeyForm(initial={'borrower': 'N/A'})
return render(request, 'catalog/keyinstance_request_update.html', {'form': form, 'keyinst':key_inst})
template
{% extends "base_generic.html" %}
{% block content %}
<div class="wrapper">
<div class="centered"> <h1>Request Keys For Room: {{keyinst.roomkey}}</h1></div>
<div class="square-box">
<div class="square-content">
<form action="" method="post" >
{% csrf_token %}
<table style="display: inline-flex">
{{ form}}
</table>
<select name = 'name'>
{% for name in names %}
<option value="{{ name }}">{{ name }}</option>
{% endfor %}
</select>
<p>
(Please use their login name i.e. <b>{{ user.get_username }}</b>)
</p>
<p><input required id="checkBox" type="checkbox" onclick="validate()"> I accept the terms and conditions</p>
<p id="text" style="display:none">You Have Agreed To the Terms and Conditions</p>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
{% endblock %}
Here is how I manged to do it, Not sure if this is the best 'pythonic' or best practice. Please let me know if it's not.
my views.py
def submit_key_request(request, pk):
"""
View function for renewing a specific keyInstance by admin
"""
key_inst=get_object_or_404(KeyInstance, pk=pk)
names = get_list_or_404(User)
# If this is a POST request then process the Form data
if request.method == 'POST':
name = request.POST['name']
key_inst.is_requested = True
key_inst.status = 'r'
key_inst.date_requested = datetime.date.today()
key_inst.borrower = name
key_inst.save()
return HttpResponseRedirect(reverse('all-available-keys') )
# If this is a GET (or any other method) create the default form.
else:
pass
return render(request, 'catalog/keyinstance_request_update.html', {'keyinst':key_inst, 'names':names})
template
{% extends "base_generic.html" %}
{% block content %}
<div class="wrapper">
<div class="centered"> <h1>Request Keys For Room: {{keyinst.roomkey}}</h1></div>
<div class="square-box">
<div class="square-content">
<form action="" method="post" >
{% csrf_token %}
</br>
<select name = 'name' required>
{% for key in names %}
<option value="{{ key }}">{{ key }}</option>
{% endfor %}
</select>
<p>
(Please use their login name i.e. <b>{{ user.get_username }}</b>)
</p>
<p><input required id="checkBox" type="checkbox" onclick="validate()"> I accept the terms and conditions</p>
<p id="text" style="display:none">You Have Agreed To the Terms and Conditions</p>
<input type="submit" value="Submit" />
</form>
</div>
</div>
</div>
{% endblock %}

Django modelformset_factory saves nothing

(I'm quite new at django, i googled for this a lot but could not find an answer, so i hope you don't mind the low level question)
There are these Classes:
class Cl(models.Model):
user = models.ForeignKey(User,editable=False)
title = models.CharField(max_length=100)
class Member(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField()
cl = models.ForeignKey(Cl)
class ClForm(ModelForm):
class Meta:
model = Cl
I want to make a page where i can create an Object of Cl and some related Member Objects (I plan to use django-dynamic-formset but that is not the point here). My view looks like this:
class NewView(TemplateView):
def get(self, request):
cform = ClForm(prefix="cl", instance=Cl(user=request.user))
MemberFormSet = modelformset_factory(Member)
memberfs = MemberFormSet(queryset=Member.objects.none())
return render_to_response(self.template_name, {'cl_form': cform, 'memberformset': memberfs}, context_instance=RequestContext(request))
def post(self,request):
cform = ClForm(request.POST, prefix="cl", instance=Cl(user=request.user))
MemberFormSet = modelformset_factory(Member)
memberfs = MemberFormSet(request.POST)
if cform.is_valid() and memberfs.is_valid():
new_cl = cform.save()
new_members = memberfs.save(commit=False)
for mf in new_members:
mf.cl = new_cl
mf.save()
return HttpResponseRedirect("unimportant")
return render_to_response(self.template_name, {'cl_form': cform, 'memberformset': memberfs}, context_instance=RequestContext(request))
My template looks like this:
<form id="myForm" method="post" action="">
{% csrf_token %}
{{ memberformset.management_form }}
<table>
{{ cl_form }}
<tr><th colspan="2">Members</th></tr>
{% with memberformset.empty_form as form %}
<div id="id_empty_form" style="display:none;">
{{ form }}
</div>
{% endwith %}
</table>
<input type="submit" value="Save" />
</form>
My problem is now, that the member is not stored. Also, the memberfs.is_valid() doens't complain, if e.g. the Email field is not filled out correctly.
I also tried the inlineformset_factory, but that didn't worked either.
I think the problem is that you are using the "empty_form" in that template. The correct way of using the formset is described here. In your example, you should write:
<form id="myForm" method="post" action="">
{% csrf_token %}
{{ memberformset.management_form }}
<table>
{{ cl_form }}
<tr><th colspan="2">Members</th></tr>
<!-- THIS IS NOT NECESSARY UNLESS YOU WANT TO ADD FORMS WITH JAVASCRIPT-->
<div id="id_empty_form" style="display:none;">
{{ memberformset.empty_form }}
</div>
<!-- END NOT NECESSARY-->
{% for form in memberformset.forms %}
{{ form }}
{% endfor %}
{% endwith %}
</tbody>
</table>
<input type="submit" value="Save" />
</form>