I'm currently working on a personal project where in a page (purchases page), there will be the main form (includes product name, product category and product specifications fields).
now, there is a link "Add New Product Category" that activates the modal. This modal includes a separate form.
What you are seeing is the final output or what I want the page to be, i only did that in html, no django coding involve.
My (stupid) question is, how am i going to display BOTH forms? I don't understand how {{form}} works.
I successfully rendered the productCategoryForm in the modal by using the code {{form}} but when I do the same in the second form productDetailsForm it's not rendering or displaying. It's blank. I'm not sure how is this going to work.
Below is my Views.py and Forms.py codes.
Views.py
def addNewProduct(response):
c_form = productCategoryForm(response.POST)
p_form = productDetailsForm(response.POST)
if response.method == "POST":
if c_form.is_valid():
a = c_form.cleaned_data["productCategField"]
b = productCategoryModel(productcategoryCol=a)
b.save()
return HttpResponseRedirect("/acctg/purchases/")
if p_form.is_valid():
c = p_form.cleaned_data["productNameField"]
d = productModel(productnameCol=c)
d.save()
return HttpResponseRedirect("/acctg/purchases/")
context = {
"p_form": p_form,
"c_form": c_form
}
return render(response, 'purchases.html', context)
Forms.py
class productCategoryForm(forms.Form):
productCategField = forms.CharField(label="Product Category", max_length=100, widget= forms.TextInput(attrs={'class':'form-control col-sm-8 col-form-label'}))
class productDetailsForm(forms.Form):
productNameField = forms.CharField(label="Product Name", max_length=100, required=True, widget=forms.TextInput(attrs={'placeholder':'Enter Product Name', 'class':'form-control col-sm-8 col-form-label'}))
Models.py
# Create your models here.
class productCategoryModel(models.Model):
productcategoryCol = models.TextField()
def __str__(self):
return self.productcategoryCol
class productModel(models.Model):
productnameCol = models.TextField()
productspecsCol = models.TextField()
#productcategCol = models.ForeignKey(productcategoryCol, default=None, on_delete=models.CASCADE)
def __str__(self):
return self.productnameCol
Appreciate your help on this. Thank you!
You can pass both forms in your template through context.
def addNewProduct(request):
p_form = productDetailsForm()
c_form = productCategoryForm()
if request.method == "POST":
p_form=productDetailsForm(request.POST)
if p_form.is_valid():
p_form.save()
return redirect("/")
context = {
"p_form": p_form,
"c_form": c_form
}
return render(response, 'purchases.html', context)
Now in the template you can render both forms with {{p_form}} and
{{c_form}}. And provide different actions and different views for both forms.
EDIT:
If you want to handle both forms with a single view then you can use the name attribute in your submit button inside your template.
template:
<form method='POST'>
{{p_form.as_p}}
<button type="submit" name="btn1">Add Product</button>
</form>
<form method='POST'>
{{c_form.as_p}}
<button type="submit" name="btn2">Add Category</button>
</form>
Now in the views.
def addNewProduct(request):
p_form = productDetailsForm()
c_form = productCategoryForm()
if request.method=='POST' and 'btn1' in request.POST:
p_form=productDetailsForm(request.POST)
if p_form.is_valid():
p_form.save()
return redirect("/")
if request.method=='POST' and 'btn2' in request.POST:
c_form=productCategoryForm(request.POST)
if c_form.is_valid():
c_form.save()
return redirect("/")
context = {
"p_form": p_form,
"c_form": c_form
}
return render(response, 'purchases.html', context)
To avoid spaghetti code I usually separate the views:
# views.py
def purchases(response):
form = productCategoryForm()
detailsForm = productDetailsForm()
return render(response, 'purchases.html', {"form": form, "detailsForm": detailsForm})
#require_POST
def add_category(request):
form = productCategoryForm(response.POST)
if form.is_valid():
a = form.cleaned_data["productCateg"]
b = productCategory(productCat=a)
b.save()
return HttpResponseRedirect("/acctg/purchases/")
#require_POST
def add_product_details(request):
form = productDetailsForm(response.POST)
if form.is_valid():
# your logic here
b.save()
return HttpResponseRedirect("/acctg/purchases/")
# urls.py
path('purchases/', purchases, name='purchases'),
path('add_category/', add_category, name='add_category'),
path('add_product_details/', add_product_details, name='add_product_details'),
# purchases.html
<form action="{% url 'add_category' %}" method="post">
{% csrf_token %}
{{form}}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
<form action="{% url 'add_product_details' %}" method="post">
{% csrf_token %}
{{detailsForm}}
<button type="submit" class="btn btn-primary">Submit</button>
</form>
Related
How can I create a multiselect dropdown checkbox (checked=True, unchecked=False) to update my models?
Below is my current code:
models.py:
class TestProfile(models.Model):
revenue = models.BooleanField(default=False)
costOfRevenue = models.BooleanField(default=False)
forms.py:
class CreateTestProfile(forms.ModelForm):
class Meta:
model = TestProfile
fields = '__all__'
views.py:
def test(request):
profile_form = CreateTestProfile()
if request.method == 'POST':
profile_form = CreateTestProfile(request.POST)
if profile_form.is_valid():
profile_form.save()
return redirect('/dashboard')
else:
profile_form = CreateTestProfile()
return redirect('/dashboard')
dict = {'profile_form': profile_form}
return render(request, 'demo/test.html', dict)
test.html:
<div class="w-1/2">
<form method="POST">
{% csrf_token %}
{{profile_form|crispy}}
<input type="submit" value="Submit">
</form>
</div>
If the dropdown is checked for revenue, then I would like to update the TestProfile model's revenue value to be True.
I have a django form, but it's not showing the "upload file" field when I render it on my website. What am I doing wrong? Ideally, the form has a question ID associated with it that's submitted automatically (e.g. it doesn't have to be manually put in by the user when uploading the file)
models.py
class Choice(models.Model):
question = models.ForeignKey(Question, on_delete=models.CASCADE)
response_file = models.FileField(upload_to='audio_responses')
forms.py
class PostAudio(forms.ModelForm):
class Meta:
model = Choice
fields = ('response_file',)
views.py
def QuestionRecordSubmitView(request, pk):
model = Question
if request.method == 'POST':
form = PostAudio(request.POST, request.FILES)
if form.is_valid():
form.instance.question_id = pk
form.save()
# get survey pk
question_instance = Question.objects.get(pk=pk)
survey_pk = question_instance.survey.pk
return redirect('survey-share',pk=survey_pk)
else:
form = PostAudio()
return render(request, 'survey/question_audio_submit.html')
html
{% extends "landing/base.html" %}
{% block content %}
<h2>New Submission</h2>
<form method="POST" class="post-form" enctype="multipart/form-data">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-default">Save</button>
</form>
{% endblock content %}
def QuestionRecordSubmitView(request, pk):
model = Question
if request.method == 'POST':
form = PostAudio(request.POST, request.FILES)
if form.is_valid():
form.instance.question_id = pk
form.save()
# get survey pk
question_instance = Question.objects.get(pk=pk)
survey_pk = question_instance.survey.pk
return redirect('survey-share',pk=survey_pk)
else:
form = PostAudio()
return render(request, 'survey/question_audio_submit.html', {'form':form})```
I have a very simple form, form1 [Rendered on template1] that takes in text for a required field. Clicking Submit on this form will lead to form2, [Rendered on template2]. On template2, I also display the data from the text field entered in form1. form2 has two fields, subject and body, along with a hidden field that is supposed to store the value of text field from form1. After clicking submit on form2, how do I now print out all data (acquired from both forms) on template3?
This is what I have so far:
Form1:
class EmailForm(forms.Form):
product_code = forms.CharField(required=True, max_length=100, label='Enter Product Code')
Form2:
class CustomersWhoBoughtForm(forms.Form):
subject = forms.CharField(required=True, max_length=1000, label='Email Subject')
body = forms.CharField(widget=forms.Textarea({'rows': 5}),
required=True, label=mark_safe('<br>Body'))
database_product_code = forms.CharField(required=True, widget=forms.HiddenInput())
Views.py
def email_customers(request):
if request.method == 'POST':
if form.is_valid():
# raise Exception(request.POST.get('product_code')) - Executing this line successfully
if request.POST.get('form_submit') == 'fetch_code':
product_code = request.POST.get('product_code')
form2 = CustomersWhoBoughtForm(initial={'databse_product_code': product_code})
return render(request, 'thanks.html', {'product_code': product_code, 'email_id': 'xyz#ecample.com', 'form2': form2})
if request.POST.get('form_submit') == 'send_email':
form2 = CustomersWhoBoughtForm(request.POST)
form2['database_product_code'] = form.cleaned_data['product_code']
if form2.is_valid():
database_product_code = request.POST.get('database_product_code')
email_subject = request.POST.get('subject')
email_body = request.POST.get('body')
return render(request, 'email_sent.html', {'email_subject': email_subject,
'email_body': email_body,
'database_product_code': database_product_code,
'recipient': 'xyz#example.com'})
else:
return render(request, 'thanks.html', {'form2': form})
else:
form = EmailForm
return render(request, 'email_customers.html', {'form': form})
else: #Logic Starts here
form = EmailForm()
return render(request, 'email_customers.html', {'form': form})
Template1 - email_customer.html
<h1>Hello</h1>
<p>Email customers page!</p>
<title>Email Customers</title>
<form action="." method="post">
{{form}}
{% csrf_token %}
<button name="form_submit" type="submit" value="fetch_code">Submit</button>
</form>
Template2 - thanks.html
<h3>Thanks for Submitting</h3>
<p>Have a good Day!</p>
<p>You submitted</p>
Product Code: {{product_code}}<br>
Email ID: {{email_id}}
<br><br><br>
<form action="." method="post">
{{form2}}<br>
{% csrf_token %}
<br><button name="form_submit" type="submit" value="send_email">Submit</button>
</form>
Template3 - email_sent.html
Subject: {{email_subject}}
<br><br>
Body: {{email_body}}
<br><br>
Product Code: {{database_product_code}}
<br><br>
Sender: {{recipient}}
<br><br>
Recipient: {{recipient}}
I'm not able to see the django form in my template. it is not being rendered properly. I've tried working on this, but the form not shows up. Tried the same code in a new project to test-that worked fine but here it doesn't work. This {{ form.as_p }} not shows up anything i.e. no input fields for me to enter the details and check the other part. Thanks in advance.
# forms.py
class ContactForm(forms.Form):
contact_name = forms.CharField(required=True)
contact_email = forms.EmailField(required=True)
contact_subject = forms.CharField(required=True)
content = forms.CharField(
required=True,
widget=forms.Textarea
)`
and:
# views.py
def contact(request):
form_class = ContactForm
if request.method == 'POST':
form = form_class(data=request.POST)
if form.is_valid():
contact_name = request.POST.get(
'contact_name'
, '')
contact_email = request.POST.get(
'contact_email'
, '')
contact_subject = request.POST.get(
'contact_subject'
, '')
form_content = request.POST.get('content', '')
# Email the profile with the
# contact information
template = get_template('contact_template.txt')
context = Context({
'contact_name': contact_name,
'contact_email': contact_email,
'contact_subject' : contact_subject,
'form_content': form_content,
})
content = template.render(context)
email = EmailMessage(
"New contact form submission",
content,
"Your website" +'',
['youremail#gmail.com'],
headers = {'Reply-To': contact_email }
)
email.send()
return redirect('contact')
return render(request, 'contact.html', {
'form': form_class,
})
The template for the same looks like this.
template
<section id="contact">
<div class="container text-center">
<div class="row text-center">
<div class="bg-image">
<div class="col-md-6 col-md-offset-3 text-center share-text wow animated zoomInDown heading-text">
<p class="heading">
If you got any questions, please do not hesitate to send us a message.
</p>
</div>
</div>
</div>
{% block content %}
<h1>Contact</h1>
<form role="form" action="" method="post">{% csrf_token %}
{{ form.as_p }}
<button type="submit">Submit</button>
</form>
{% endblock %}
</div>
</section>
Add an else clause for generating a form on GET:
def contact(request):
form_class = ContactForm
if request.method == 'POST':
form = form_class(data=request.POST)
# ... more code from above ...
else:
form = form_class() # this is important
return render(request, 'contact.html', {
'form': form, # NOTE: instead of form_class!!!!
})
You are passing the form class to your template instead of a form instance.
You haven't handled the case when request.method is not POST.
Your view should look like this:
def contact(request):
if request.method == 'POST':
form = ContactForm(request.POST)
if form.is_valid():
# form handling logic here
# ...
# ...
return redirect('some-link')
else:
return render(request, 'template.html', dict(form=form))
else:
form = ContactForm()
return render(request, 'template.html', dict(form=form))
Please, help.. I do not udersatand what I should do this code to work..
home.html:
<form class="subscribe-form" action="{% url 'subscribe' %}" method="POST">{% csrf_token %}
{{ form }}
<button class="btn btn-main btn-lg" type="submit">Подписаться!</button>
</form>
{% if success %}
<div class="subscribe-result">
{{ success }}
</div>
{% endif %}
urls.py:
url(r'^$', 'interior_app.views.home', name='home'),
url(r'^subscribe/$', 'interior_app.views.subscribe', name='subscribe')
models.py:
class Subscriber(models.Model):
email = models.EmailField('', max_length=100, null=True, blank=True)
forms.py:
class SubscriberForm(forms.ModelForm):
class Meta:
model = Subscriber
fields = ['email']
admin.py:
class SubscriberAdmin(admin.ModelAdmin):
list_display = ('email',)
admin.site.register(Subscriber, SubscriberAdmin)
views.py:
def home(request):
portfolios = PortfolioObject.objects.all()
photos = []
for portfolio in portfolios:
for obj in portfolio.photo_set.all():
photos.append(obj)
form = SubscriberForm()
context = {"photos": photos[::2], "form": form}
return render(request, "home.html", context)
def subscribe(request):
print request
success = ''
if request.method == "POST":
print request.POST
form = SubscriberForm(request.POST)
print form
if form.is_valid():
form.save()
success = "Ваш Email успешно отправлен"
form = SubscriberForm()
else:
form = SubscriberForm()
context = {"photos": photos[::2], "form": form, "success": success}
return render(request, "home.html", context)
I input email in the form, push button and nothing is happening.
Any data in admin, any {{ success }}.
I need not AJAX.. I would like to do this feature only with Django