Django Generating Form with Hidden Input in forloop - django

I have to dynamically populate a form with hidden input in a forloop.
I am doing it like this:
my form class is:
class RemoveFromCartForm(forms.Form):
pass
It has no fields, for i intend to use this in order to use class-based views and do form handling.The crux is i am trying to dynamically generate a form with few hidden input as follows:
{% for cart_item in cart.cartitems.all %}
<p>{{cart_item}}</p>
<form method="POST" action="">{% csrf_token %}
{{form.as_p}}
<input type="hidden" name="cartitem" value="{{cart_item.pk}}" />
<input type="hidden" name="cart" value="{{cart.pk}}" />
<input type="submit" value="remove">
</form>
{% endfor %}
my views class is as follows:
class AddToCart(DetailView, BaseFormView ):
form_class = RemoveFromCartForm
model = Cart
context_object_name = 'cart'
template_name = 'cart/add-to-cart.html'
def get_object(self,queryset=None):
return Cart.objects.get(cart_id=self.request.session['CART_ID'])
def form_valid(self, form):
cleaned_data = form.cleaned_data
#return something
problem is my form.cleaned_data is {}, though i am using forloop to populate some hidden input on the fly. How can i add those hidden inputs so i get them in my form_valid class ?

I can't help but notice form_valid() doesn't have a return statement
This is from official django doc ,check the example of overriding form_valid method
https://docs.djangoproject.com/en/dev/topics/class-based-views/generic-editing/

Related

How to fill form fields since HTML

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.

How to link my HTML form to a view class in Django

post_form.Html
This is an Html Page With Form to Update and Create As We Know that Create And Update View Class in Django used the same form
<form method="post">
{% csrf_token %}
<div class="form-group">
<label for="PostInput">PostTitle</label>
<input class="form-control" type="text" name="post" placeholder="Name" value="{{ post.postname }}">
</div>
<div class="form-group">
<label for="descrInput">Description</label>
<input class="form-control" type="text" id="descrInput" placeholder="Description" value="{{ post.description }}">
</div>
<input type="submit" value="Save">
</form>
Views.py
class CreatePost(CreateView):
model = post
fields = ['title', 'content']
class UpdatePost(UpdateView):
model = post
fields = ['title', 'content']
Now, the question is how can i link this form with the above html page which already has form or input fields in the web page itself. I know how to do it using function views but i am not getting any materials, tutorials anything about this. Any Material regarding this will be helpful
You can override CreateView().post() and UpdateView().post() methods like this
class CreatePost(CreateView):
model = post
fields = ['title', 'content']
def post(self, request, *args, **kwargs):
# Get your data from post request eg. request.POST['mykey']
return redirect('success_page')
class UpdatePost(UpdateView):
model = post
fields = ['title', 'content']
def post(self, request, *args, **kwargs):
# Get your data from post request eg. request.POST['mykey']
return redirect('success_page')
Note : You've created your post model class in lowercase which is not good practice always name a class in CapWords. Because you have written your class in lowercase python will treat your post class as a post method or it may lead to logical error.

django form populate multiple identical field form in one submit

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>

Django - Forms - autofill & hide foreign key field

I have models.py, and forms.py that looks like this:
class BHA_overall(models.Model):
bha_number = models.ForeignKey(BHA_List, 'CASCADE', related_name='bha_overall')
drill_str_name = models.CharField(max_length=111)
depth_in = models.CharField(max_length=111)
depth_out = models.CharField(max_length=111)
class BHA_overall_Form(forms.ModelForm):
class Meta():
model = BHA_overall
fields = '__all__'
In my template, if I just use:
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<button name='action' value='login' type="submit">Sign in</button>
</form>
the foreign key field bha_number is displayed as a combo box where I can select the specific bha_number model instance it belongs to, like this:
Here, I want to remove Bha number field from the user side, and just let my code auto fill that field for the user, and hide it. So from the user side, there will be only 3 fields displayed. How can I do this?
Currently I am implementing this html code:
<form id="demo-form" data-parsley-validate="" novalidate="" method="POST">
<div class="row">
{% csrf_token %}
{% for field in form %}
<div class="col-lg-2 col-md-2 col-sm-4 col-xs-6" style="margin-bottom: 5px">
<label class="input-upper-title">{{ field.name }}</label>
<input type="text" id="" class="form-control input-field-height-vertical" name="" data-parsley-trigger="" required="">
</div>
{% endfor %}
<input type="submit" class='btn btn-primary' value="Submit">
</div>
</form>
And it renders this:
I want the first field, bha_number to disappear from the user side, but the system still needs to get that information to save to a correct model instance. So I'm looking for an way to auto fill this ForeignKey field at forms.py or views.py level.
Here is my views.py:
class BHA_UpdateView(UpdateView):
model = BHA_List
success_url = reverse_lazy('well_list') # this is wrong
form_class = BHA_overall_Form
def post(self, request, **kwargs):
api = get_well_api(self.request)
current_bha = BHA_List.objects.filter(id=get_current_bha_id(self.request))[0]
form = BHA_overall_Form(request.POST, instance=BHA_overall.objects.filter(bha_number__well__api=api, bha_number=current_bha)[0])
if form.is_valid():
form.save()
return super().post(request, **kwargs)
You can use exclude to hide the field from form
Class BHA_overall_Form(forms.ModelForm):
class Meta():
model = BHA_overall
fields = '__all__'
exclude = ('bha_number',)
To auto fill after checking if form is valid, just clean the data using form = form.cleaned_data and store it in any variable. It's nothing but a dictionary. You can assign value to this like form['bha_number'] = your value and save it to database by using form.save().
Or you can use object = form.save(commit=False) because this method will return an object. Then you can do object.bha_number = your number
And finally object. Save in next line. That's all. Choose whatever solution you like.
Why don't you keep it as is on forms.py but exclude it from your HTML? That way the user would not see it as an option but the value would still be sent with the form.

Create parent and children model objects from one form submission

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 ;)