I have been looking for information on the web about how set values in forms of django but it has been really difficult.
I need to put "Inicio" in the field "Origen_del_Circuito" after pushing the button, I have this code:
Forms.py
class CargaElectricaForm(forms.Form):
Circuito=forms.CharField(label='Circuito', max_length=200)
Origen_del_Circuito=forms.CharField(label='Origen del Circuito', max_length=200 )
views.py
def bajatension(request):
if request.method=="POST":
form=CargaElectricaForm(request.POST)
if form.is_valid():
#form.save()
c="Inicio"
return render (request, 'SizingWires/lowvoltage.html',{'form':form,'c':c})
else:
form=CargaElectricaForm()
return render (request, 'SizingWires/lowvoltage.html',{'form':form})**
lowvoltage.html
<form method="post" >
{% csrf_token %}
<table>
{{form.as_table}}
</table>
<input type="submit"> Calculator</button>
<input type="text" value="{{c}}">
</form>
It doesn't work because it creates a new input and I need to use the field "Origen_del_Circuito". How can I access to the fields of my form since HTML (file lowvoltage.html) to put the value of "c"?
I know the method "initial" however I need to put the value after of pushing the button.
Related
I am working on a Django project whose purpose is to allow the user to fill in some forms. In some of these forms, the user must make a choice between several options and, based on the choice made, a particular form must be generated. At the end of all these forms, the data entered must be used to write a pdf file.
As for the functionality related to generating the pdf, what I'm interested in for the purposes of the question is the use of data entered in one view in another view using them as context.
Here's what I tried to do.
First of all I created some forms in forms.py:
class ChoiceForm(forms.Form):
CHOICES = [
('1', 'Choice-One'),
('2', 'Choice Two'),
]
choice = forms.ChoiceField(choices=CHOICES)
class ChoiceOneForm(forms.Form):
name_one = forms.CharField(max_length=200)
class ChoiceTwoForm(forms.Form):
name_two = forms.CharField(max_length=200)
Then I created this view in views.py:
def contact(request):
if request.method == 'POST':
num_people = int(request.POST.get('num_people'))
people_formset = [forms.ChoiceForm() for i in range(num_people)]
return render(request, 'home.html', {'people_formset': people_formset})
else:
return render(request, 'home.html')
def generate_pdf(request):
context = {}
return render(request, 'pdf.html', context)
And finally I have this HTML file called 'home.html':
<h1>Contact</h1>
<form method="post">
{% csrf_token %}
People number: <input type="number" name="num_people" required>
<input type="submit" value="Submit">
</form>
{% if people_formset %}
{% for form in people_formset %}
<form>
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit">
</form>
{% endfor %}
{% endif %}
what I've been able to achieve so far is to generate as many 'choice' fields as the value of the number entered in the 'num_people' field.
What I'm missing is:
1. Being able to create, for each 'choiche' field in the formset, a ChoiceOneForm or ChoicheTwoForm form based on the choice made in the 'choice' field;
2. Being able to use all this data in the 'generate_pdf' view (for now what interests me is being able to include this data in the context of this view).
Long story short , My form.html Only shows submit button rather than all the fields of the model form
<div class="form">
<form action="{% url 'name' %}" method="POST">
{% csrf_token %}
{{ form }}
<input type="submit" value="submit">
<p style="color: red;">Watch it before it gets removed on The Internet</p>
</div>
Here is forms.py
from django import forms
from django.forms.models import ModelForm
from .models import Person
class PersonForm(forms.ModelForm):
class Meta:
model = Person
fields = ['name','email']
when I tried adding html inputs manually on forms.html I was able to make the inputs show on the page , Is something wrong with importing model form like that ??
Also what's weird is that when I click on that submit button since its the only one showing on the page … It takes me to a plain form.html with validation error , since I was submitting empty values
Here is how I include it in the Parent template {% include "form.html" %}
This is my view for that form
def get_name(request):
if request.method=="POST":
form = PersonForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('thank-you'))
else:
form = PersonForm()
return render(request,'form.html',{ 'form': form })
It works well when I don't just include in other template when it is all alone
I don't want to use django form class as they will not give me much flexibility.
I have a form where will random number field in easy request. i am trying to populate the multiple value of forms that appears.
this is my models.py
class Profile(models.Model):
name = models.CharField(max_length=100)
photo = models.FileField()
and this my form.html
<form method="POST" action="{% url 'form' %}">
{% csrf_token %}
{% for i in range %}
<input type="text" id="name" name="name"><br>
<input type="file" id="photo" name="photo"><br><br>
{% endfor %}
<input type="submit" value="Submit">
</form>
You may notice I am rendering field with for loop.
that is means, there will be as much field as possible can be appear based on user request.
So I want to populate these models.
my view looks like
def form_view(request):
if request.method == 'POST':
# Need to puplate the form
return render(request, 'form.html', {'range': range(40)})
Can anyone please help me how can i achieve this? i am just struggling to achieve this.
you can use modelformset_factory for this. this way,
in your views.py
from .models import Profile
from django.forms import modelformset_factory
def form_view(request):
form_range = 40 # set the range here
ProfileFormSet = modelformset_factory(Profile, fields=("name", "photo"), extra=form_range, max_num=form_range)
formset = ProfileFormSet(request.POST or None)
if request.method == "POST":
if formset.is_valid():
formset.save()
return render(request, "form.html", {"profile_formset": formset})
and in your form html
<form method="POST" action="{% url 'form' %}">
{% csrf_token %}
{{ profile_formset.as_p }}
<input type="submit" value="Submit">
</form>
I am trying to create an 'add user' feature which will simply add the user you've selected from a dropdown as your connection. I am using ModelChoiceField from Django Forms so that I may get the existing users from my User model in the dropdown.
forms.py
from django import forms
from django.contrib.auth.models import User
class NetworkForm(forms.Form):
user_id = forms.ModelChoiceField(queryset=User.objects.all(), label='',
widget=forms.Select(attrs={'class': 'all_users'}))
views.py
#login_required
def index(request):
user_list = User.objects.exclude(username=request.user)
return render(request, 'chat/index.html', {'user_list': user_list})
For now I am just printing the form to see output
#login_required
def add_user(request):
form = NetworkForm()
if request.method == 'POST':
form = NetworkForm(request.POST)
if form.is_valid():
print form
return redirect(request.META['HTTP_REFERER'])
errors = form.errors or None
return render(request, 'chat/index.html', {
'form': form,
'errors': errors,
})
index.html
<div class="row">
<form action="{% url 'chat:add_user' %}" method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button>
</form>
</div>
urls.py
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^add_user/$', views.add_user, name='add_user'),]
The way it is being rendered currently is: I have my main index page where I don't see any dropdown, i.e.,
When I click on the submit button, it moves me to index/add_user, where I get a dropdown with user (with a warning "this field is required) and a submit button again.
Finally, when I choose a user in this new page and hit submit, finally the form is printed, which I want ultimately.
What I would want it, have the complete form with dropdown in the index page itself and remain there when I submit the form. I will then hook that to show user the users they have added beneath that form itself ('print' is just for debugging purpose - not a good way I've heard though).
I understand the post request will have to go to add_user page and I can redirect back from that. I have tried various alternatives for the past 6 hours, nothing works yet. Apologies for a long one, giving out information as much as possible. Thanks very much guys. You are awesome.
Edit
Have been now rendering the form in index page (suggestion from #fazil-zaid ), but the issue remains as in only 'submit' button appears on index initially, unless when I hit submit after which the dropdown and submit appears. Again, on clicking the second time, the form is submitted.
Edit-2
I am thinking that:
<form action="{% url 'chat:index' %}" method="post">{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button>
</form>
this might be where the problem is, as per current logic unless user takes form's action, i.e., clicks the button {{ form.as_p }} will not appear. Then I tried:
{{ form.as_p }}
<form action="{% url 'chat:index' %}" method="post">{% csrf_token %}
<button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button>
</form>
Doesn't work still. POST request doesn't send any data (understandably so).
If you want the form to be in the index page, then you could include it in the index view itself.
def index(request):
if request.method == 'POST':
form = NetworkForm(request.POST)
if form.is_valid():
#do what you wanna do
#with the form data.
else:
form = NetworkForm()
render(request, 'chat/index.html', { 'form': form})
In the template,
<div class="row">
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-warning" value="{{ user_id }}" style="float: left;">Submit</button>
</form>
</div>
You are not rendering another template, but the same 'index.html'. Then, multiple view for that is just redundant. Index page could contain the form and render itself. From what I understand, there's no need of redirections.
There's no need of add_user view if you're showing the form in the index page itself.
For your issue, try changing the "class" attribute of the form fields, maybe something like this,
class NetworkForm(forms.Form):
user_id = forms.ModelChoiceField(queryset=User.objects.all(), widget=forms.Select(attrs={'class': 'form-control'}))
Solution:
When the page is called in the first instance using GET, the form is not valid as it seeks a POST method. Hence, all the method need to be changed to POST in the view, i.e.,
#login_required
def index(request):
user_list = User.objects.exclude(username=request.user)
form = NetworkForm()
if request.method == 'POST':
form = NetworkForm(request.POST)
if form.is_valid():
print form.data
return redirect(request.META['HTTP_REFERER'])
return render(request, 'chat/index.html', {
'user_list': user_list,
'form': form,
})
Earlier, index was using a GET to render data to index page, and using a POST to use the form. Now, everything works fine.
Special shout-out to #fazil-zaid for the heads-up since you mentioned to include everything in the index view itself, rather than making a separate view for form. Your code pointed that out in a way in addition to Stack here.
My model has a parent object, each of which can have zero or more child objects associated by foreign key.
My auto-generating ModelForm works great for the parent object, but I'd like the user to be able to create one or more of the child objects at the same time as creating the parent. Note, I don't mean pick from pre-existing child objects - I do mean create child objects from scratch...
I'm currently using lots of django magic to get the form to appear with very little boilerplate from me: I realise that will probably have to change to get this done!
Here's an idea of what I have at the moment:
# urls.py
(r'^create/$',
CreateAppView.as_view(
model=App,
template_name='edit.html')),
# edit.html
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
# model
class App(models.Model):
name = models.CharField(max_length=100)
class Activation(models.Model):
app = models.ForeignKey(App)
# view
class AppForm(ModelForm):
class Meta:
model = App
class CreateAppView(CreateView):
def post(self, request, *args, **kw):
form = AppForm(request.POST)
if form.is_valid():
app = form.save()
return HttpResponseRedirect(reverse('app_detail', args=(app.id,)))
else:
return super(CreateAppView, self).post(request, *args, **kw)
Actually, all this sort of functionality is provided already in the form of inline model formsets.
add multiple forms with different names ?
The problem then is you'll have to know how many forms are being rendered and have a much more specific template.
something like:
# edit.html
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ appform.as_p }}
{{ appform2.as_p }}
<input type="submit" value="Submit" />
</form>
and in the view:
appform= AppForm(request.POST, prefix="1")
appform2= AppForm(request.POST, prefix="2")
It will also work for diffferent models:
appform= AppForm(request.POST, prefix="app")
spamform = SpamForm(request.POST, prefix="spam")
I'm not sure about your urls.py because i've never used that function/shortcut ... thingy ;)