pass parameter to form from template in Django 2 - django

in Django I make a form which get an email address and save it in database and this my form.py:
class NewsletterUserSignUpForm(forms.ModelForm):
class Meta:
model = NewsletterUsers
fields = ['email']
def clean_email(self):
email = self.cleaned_data.get('email')
return email
and this is my views.py :
def newsletter_signup(request):
form = NewsletterUserSignUpForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
if NewsletterUsers.objects.filter(email=instance.email).exists():
messages.warning(request, 'Your Email Already Exist In Our DataBase.',
'alert alert-warning alert-dismissible')
else:
instance.save()
messages.success(request, 'Your Has Been Submitted To Our DataBase.',
'alert alert-success alert-dismissible')
context = {
'form': form,
}
return render(request, 'newsletter/subscribe.html', context)
the problem is here that this form has it own input which the input must put inside it but I want to design my own template and get input in my template then pass it to this form and my question is how do I can pass inputs in my .html template file to my form?
this is my html file and don't know to put what in href for input tag :
<form method="post" class="login100-form validate-form">
{% csrf_token %}
<span class="login100-form-title p-b-43">
Subscribe
</span>
<div>
<inputtype="email" name="Email">
<span class="label">Email</span>
</div>
<button type="submit" href="">
Subscribe
</button>
</div>
and what should I put in my href and how pass input to form from here?
In addition, I'm sorry for writing mistakes in my question.

From what I understand, you want to create your own custom input box and when that box is filled, you want the form input box to also get filled.
Hide the form input box using display:none.
Create your own custom input box, use javascript to fill the form input box when custom input box is filled.
Ex :
<script>
form_input_box = document.getElementById('id_of_form_input_box')
custom_input_box = documen.getElementById('id_of_custom_input_box')
$("id_of_custom_input_box").change(function(){
form_input_box.value = custom_input_box.value
});
</script>

the problem it was for my html code, I Should add an id and name attribute to my input tag and use this id and name for getting input from html and pass it to my form, and for href attribute I write the url that redirect to my form.
fixed html code:
<form method="post" class="login100-form validate-form">
{% csrf_token %}
<span class="login100-form-title p-b-43">
Subscribe
</span>
<div class="wrap-input100 container-login100-form-btn rs1 rs2 validate-input padding-50"
data-validate="Username is required">
<input id="email" maxlength="100" class="input100" type="email" name="email">
<span class="label-input100">Email</span>
</div>
<div class="container-login100-form-btn">
<button type="submit" href="{% url 'newsletter_subscribe' %}" class="login100-form-btn">
Subscribe
</button>
</div>
<div class="text-center w-full p-t-23">
<a style="font-size: 15px" href="{% url 'newsletter_unsubscribe' %}" class="txt1">
Click Here To Unsubscribe.
</a>
</div>
</form>

Related

Access data from html form in Django

I have created a form in an application that goes like this :
<form action="" style="max-width:500px;margin:auto">
<div class="input-container_sensor_form">
<div class="row">
<div class="col-6">
<input class="input_field_sensor_form" type="text" placeholder="Sensor name" name="sensor_name">
</div>
<div class="col-6">
<span class="text-center">
<select name="sensor_form_sensor_category" class="sensor_form_sensor_category" id="sensor_form_sensor_category" class="select2-hidden-accessible" aria-hidden="true" data-select2-id="sensor_form_sensor_category">
<option></option>
<option name="tree_sensor" >Tree Sensor</option>
<option name="weather_sensor" >Weather Station</option>
</select>
</span>
</div>
</div>
</div>
<div class="row">
<div class="col-6">
<input class="input_field_sensor_form" type="text" id="latitude" placeholder="Latitude" name="latitude">
</div>
<div class="col-6">
<input class="input_field_sensor_form" type="text" id="longitude" placeholder="Longitude" name="longitude">
</div>
</div>
</div>
<br>
<div id="map_sensor_form"></div>
<br>
<input type="hidden" id="field_id" name="field_id" value="">
<button type="submit" class="btn_sensor_form">Register</button>
</form>
with the following form :
class AddSensor(forms.Form):
sensor_name = forms.CharField(max_length=200 )
choice = forms.ChoiceField()
longitude = forms.DecimalField(max_digits=22, decimal_places=16)
latitude = forms.DecimalField(max_digits=22, decimal_places=16)
How do i match the inputs with the form ? I've seen in the django doc that its referencing it through label but I do not have any. I want to keep the form as it is .
you can make use of form.cleaned_data
create a model instance and assign values from form.cleaned_data
to form.is_valid() work, you can make sure that the html field id is same as that of AddSensor form field.
for instance: AddSensor form field sensor_name and html field with id sensor_name
# views.py
from .models import YourModel # import model
from .forms import AddSensor # import form
def your_view(request):
if request.method == 'POST':
form = AddSensor(request.POST)
if form.is_valid():
form_data = form.cleaned_data
obj = YourModel()
obj.sensor_name = form_data.get("sensor_name")
# other fields
obj.save()
# return or redirect
else:
form = AddSensor()
return render(request, 'your_template.html', {'form': form})
here, instead of rendering the form using django forms, the form is hardcoded with the same id's that a django form would render. By matching the id's in the hardcoded html and django form, form.is_valid() can be called. thus form.cleaned_data can be accessed with the form field names

How to Add Subscribe option in a Django Website

I am trying to add a subscribe to newsletter option on a django website. When a visitor enters
a valid email address it will be stored in the database. The subscription form is part of the base.html template.
All other templates of the website extend this template. I wish to implement this in a DRY way.
This is how I am trying to do it :
forms.py :
from dataclasses import fields
from django import forms
from . models import Subscribers, MailMessage
class SubcribersForm(forms.ModelForm):
class Meta:
model = Subscribers
fields = ['email', ]
views.py :
def base(request):
if request.method == 'POST':
form = SubcribersForm(request.POST)
if form.is_valid():
form.save()
return redirect('/')
else:
form = SubcribersForm()
context = {'form': form}
return render(request, 'base.html', context)
The template: base.html
<form method = "POST" class="signup-form form-inline justify-content-center pt-3">
{% csrf_token %}
<div class="form-group">
<label class="sr-only" for="semail">{{context}}</label>
<input type="email" id="semail" name="semail1" class="form-control mr-md-1 semail" placeholder="Enter email">
</div>
<button type="submit" class="btn btn-primary">Subscribe</button>
</form>
models.py :
class Subscribers(models.Model):
email = models.EmailField(null=True)
date = models.DateTimeField(auto_now_add=True)
def __str__self(self):
return self.email
In the backend, I can see that the Subscribers table has been created. However, when I enter any email address from the home
page and click subscribe button it does not store it in the database. What could be the issue here?
It could be that you have no action declared in your form. Assuming you have a url like this:
path('add-subscriber/', base, name='base'),
...your form would need a way to call it upon submit, like this:
<form method = "POST" action="{% url 'base' %}" class="signup-form form-inline justify-content-center pt-3">
{% csrf_token %}
<div class="form-group">
<label class="sr-only" for="semail">{{context}}</label>
<input type="email" id="semail" name="semail1" class="form-control mr-md-1 semail" placeholder="Enter email">
</div>
<button type="submit" class="btn btn-primary">Subscribe</button>
</form>

MultiValueDictKeyError at /savepost/

I know this has been asked before but I'm facing this MultiValueDictKeyError. Basically I'm trying to take an input from the user, the input tag has this name="usercaption" attribute. While I click on submit it pops up the MultiValueDictKeyError. Here's my HTML form:
<div class="post">
<form action="/savepost/" method="GET">
<input type="text" name="usercaption" placeholder="Write Something...">
<div class="attach">
<button class="upload-image"><i class="fal fa-image"></i> Image</button>
<button><i class="fal fa-video"></i> Video</button>
<button><i class="fal fa-smile-beam"></i> Mood</button>
<button type="submit">Upload</button>
</div>
</form>
</div>
Here's my view function:
def savepost(request):
caption = request.GET["usercaption"]
Post = post(caption=caption)
Post.save()
return redirect('usersfeed')
The error is on this line caption = request.GET["usercaption"]
You have to provide a default value for if it doesn't exist, so for example:
caption = request.GET.get["usercaption", ""]
And you have to add the user as well:
user = request.user
Post = post(caption=caption, user=user)

Multiple POST request is not working after submit

I am trying to use 2 post method in a single page one is for login and other one is for contact us
login is working fine but after submitting contact us the content of login and contact us page is gone
I tried to pass various type of dictionary but still, it's not working
app/views.py
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render
from homePage.forms import SignInForm,DropUsaMessage
# Create your views here.
def homePage(request):
if request.method == 'POST' and 'SignIn' in request.POST:
sign_in_detail = SignInForm(request.POST)
if sign_in_detail.is_valid():
return render(request, "index2.html",{})
elif request.method == 'POST' and 'SendMessage' in request.POST:
message_detail = DropUsaMessage(request.POST)
if message_detail.is_valid():
return render(request, "index.html",{})
else:
sign_in_detail = SignInForm()
message_detail = DropUsaMessage()
context={
"form":sign_in_detail,
"forms":message_detail
}
return render(request, "index.html",context)
index.html
<div class="container contact-form">
<form method="post">
<h3>Drop Us a Message</h3>
{% csrf_token %}
{{ forms }}<br><br>
<div class="form-group">
<input type="submit" name="SendMessage" class="btnContact" value="Send Message" />
</div>
</form>
</div>
<div class="container-fluid">
<div class="row">
<div class="col-md-8">
<img src="{% static 'img/sampleImage.jpg' %}" width="100%" height="100%" class="d-inline-block align-top" alt="">
</div>
<div class="col-md-4">
<form method="POST">
{% csrf_token %}
{{ form }}
<div class="form-check">
<span class="fpswd">Forgot password?</span>
</div>
<button type="submit" class="btn btn-primary" name="SignIn">Submit</button>
</form>
</div>
</div>
</div>
app/forms.py
from django import forms
from django.core import validators
class SignInForm(forms.Form):
email=forms.EmailField(widget=forms.EmailInput(attrs={"class": 'form-control',"placeholder":'Enter E-mail',"id": 'exampleInputEmail1'}))
password=forms.CharField(widget=forms.PasswordInput(attrs={"class":'form-control',"placeholder":'Enter Password',"id":'exampleInputPassword1'}))
class DropUsaMessage(forms.Form):
name = forms.CharField(widget=forms.TextInput(attrs={"class":'form-control',"placeholder":'Your Name'}))
email = forms.EmailField(widget=forms.EmailInput(attrs={"class": 'form-control',"placeholder":'Your E-mail',"id": 'exampleInputEmail1'}))
phone = forms.IntegerField(widget=forms.NumberInput(attrs={"class":'form-control',"placeholder":'Your Phone Number'}))
message = forms.CharField(widget=forms.Textarea(attrs={"class":'form-control',"placeholder":'Type Your Message',"style":'width:100%; height: 150px'}))
Expected Result:
After filling up the contact us form the field will be there.
Actual result:
there is no field in Contact us(except Send Message button) and no field in SignInForm(no e-mail and no password).
Just follow the code flow and you'll notice that in the case of a POST request and "SignIn" in the post, you return the rendered "index2.html" template without any context (form and forms will be undefined in your template). Idem for the other case:
return render(request, "index2.html", {}) # empty context
Worse, if the form posted is not valid, you'll notice you only define one for the forms and not the other one, so when the code execution reaches the line context = {"form": ..., "forms": ...}, one of them will be undefined and your view will "crash", return a 500 error.
context = {'form': sign_in_detail, # sign_in_detail never defined for second "if"
'forms': message_detail} # message_detail never define for first "if"
In general, when a POST is successful, you should always redirect to another view (or the same view). That's the internet convention, in order to avoid page reload issues that would resubmit the same data. Do this:
return redirect('home') # or whatever your homepage url pattern is called
Also, it would make more sense to post your forms to different views (change the action attribute of each of your <form> tags) so you can process them in separate views which is cleaner code:
<form action="{% url 'create_message' %}" method="post">

django the way to access data from input form

My symptom is when I click the modify button and then I write down the information on new window that is implemented by bootstrap div part. However, my database doesn't change at all. Please ignore ... in codes, I delete attributes that looks messy. Codes can have typo, because I wrote it down manually to find a bug, but I didn't find.
I tried in view.py, address_modify makes return Httpresponse(street), but It returned None.
view.py
def address_modify(request, adid):
cat = get_object_or_404(Address, adid=adid)
if request.method == "POST":
old_adid = adid
email = request.user.email
street = request.POST.get("street", None)
city = request.POST.get("city", None)
...
Address.objects.filter(adid=adid).update(..., street=street, city=city, state=state, ...)
return redirect('/address/')
return redirect('/address/')
template ( I name it address.html)
<button class="btn btn-success" data-toggle="modal" data-target="#modify">MODIFY</button>
<div class ="model fade" id="modify" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<from action="" method="POST">{% csrf_token %}
</div>
<div class="modal-body">
<input type="text" name="street">
<input type="text" name="city">
...
...
<input type="text" name="zipcode">
</div>
<div class="modal-footer">
<a href="{% url 'address_modify' i.adid %}">{% csrf_token %}
<button type="button" class="btn btn-primary">Save Change</button></a>
<div></form>
urls.py
url(r'^address_modify/(?P<adid>[0-9]+)/$', MyAppView.address_modify, name='address_modify'),
In django the best practice is to create a forms.py file to handle forms, its really easy you can read the doumentation on it, basically the form will ensure that all your data are read.
That is not how you implement form and form submit. Your link is not submitting anything, it's just opening a link. This is the standard form syntax:
<form method="POST">
{% csrf_token %}
... your form input fields here ...
<input type="submit" value="Save changes">
</form>
You must submit the form. Note type="submit" there.
Next to that, Django has forms feature. Use it. Create forms.py as #Saumel-Omole suggested. Form for model Address would look like this:
class AddressForm(forms.ModelForm):
class Meta:
model = Address
fields = '__all__'
Then you modify your view to use the form like:
def address_modify(request, adid):
cat = get_object_or_404(Address, adid=adid)
form = AddressForm(instance=cat)
if request.method == 'POST':
form = AddressForm(request.POST, instance=cat)
if form.is_valid():
form.save()
return redirect('/address/')
else:
print(form.errors) # change to logging
return render(request, 'address.html', {'form': form})
Go over the official Django tutorial. These basics are all there. Maybe it is going to take you a day or two to get through it, but long-term that's going to be far less than guessing and googling around for days for basic stuff.