I have created one html form for my web application. Now I want to fetch data for further validation on submit the form in DJANGO. So how can I do this. I have attached my html form code below. Actually, I can get the data by the request.POST.get('field_name') method but I want to get data in the single object. Also I want to create seprate python file for validation. So how can I redirect on that file.
<form action="/contact_form_data_insert" name = "contact_us_form" id = "contact_us_form" method="POST">
<div class="bg-transperent container mt-6">
<div class="bg-transperent container">
<div class="row bg-transperent">
<div class="col-lg-6 bg-transperent contact_field">
<div class="form-outline my-2 px-2" >
<input type="text" id="contact_name" name="contact_name" class="form-control form-control-lg-border-0" placeholder = "Your Name"/>
</div>
</div>
<div class="col-lg-6 bg-transperent contact_field">
<div class="form-outline my-2 px-2" >
<input type="text" id="contact_company" name="contact_company" class="form-control form-control-lg-border-0" placeholder = "Your Company" />
</div>
</div>
</div>
<div class="row bg-transperent">
<div class="col-lg-6 bg-transperent contact_field">
<div class="form-outline my-2 px-2" >
<input type="tel" id="contact_phone_number" name="contact_phone_number" class = "form-control form-control-lg-border-0" placeholder = "Phone Number">
</div>
</div>
<div class="col-lg-6 bg-transperent contact_field">
<div class="form-outline my-2 px-2" >
<input type="email" id="contact_email" name="contact_email" class="form-control form-control-lg-border-0" placeholder = "Email"/>
</div>
</div>
</div>
</div>
<div class="bg-transperent container">
<div class="row">
<div class="col-12 bg-transperent contact_field ">
<div class="form-outline my-2 px-2" >
<input type="text" id="contact_subject" name = "contact_subject" class="form-control form-control-lg-border-0" placeholder = "Subject" />
</div>
</div>
</div>
</div>
<div class="bg-transperent container">
<div class="row">
<div class="col-12 bg-transperent contact_field">
<div class="form-outline my-2 px-2" >
<textarea class="form-control form-control-lg-border-0" id="contact_question" name="contact_question" placeholder = "Your Question" rows="5"></textarea>
</div>
</div>
</div>
</div>
<div class="container bg-transperent">
<div class="row">
<div class="col-lg-2 px-4">
<input type="submit" class = "btn btn-info btn-lg btn-block"style="color: white;font-family: serif; font-weight: bolder; " value="SEND">
</div>
</div>
</div>
</div>
</form>
Make Django form in the backend for example login form has username and password fields
Don't use it in the front
Just make your own form in the front end with fields named username and password
Django of course can't tell if the data sent from Django form or custom form
So it'll treat it normally
For example
class LoginForm(Form):
username = ...
password = ...
class Meta:
fields = ('username', 'password')
Now in the backend
form = LoginForm (request.POST)
if form.is_valid():
The form only needs data named username and password from the front side
About using Django forms, here's a quick demo... You can create a file within your app folder called forms.py and place the following inside of it.
from django import forms
class ContactForm(forms.Form):
# You can also modify the field attributes from here if you wish to
contact_name = forms.CharField(widget=forms.TextInput(attrs={'id':'contact_name', 'name': 'contact_name', 'class': 'form-control form-control-lg-border-0', 'placeholder': 'Your Name'}))
# You can take the same approach for the other text & email input fields below
contact_company = forms.CharField(widget=forms.TextInput(attrs={...}))
contact_phone_number = forms.CharField(widget=forms.TextInput(attrs={...}))
contact_subject = forms.CharField(widget=forms.TextInput(attrs={...}))
contact_email = forms.EmailField(widget=forms.EmailInput(attrs={...}))
# Textarea field
contact_question = forms.CharField(widget=forms.Textarea(attrs={'id':'contact_question', 'name': 'contact_question', 'class': 'form-control form-control-lg-border-0','placeholder': 'Your Question', 'rows': '5'}))
# Can create any method in here to handle a specific process if the form is valid
def save(self):
pass
From your views.py file within the same app folder:
from .forms import ContactForm # Importing the custom form you created
# Now let's say I want to pass it to a specific view to allow a user to submit his/her information...
def contact_form_view(request):
if request.method == 'POST':
form = ContactForm(data=request.POST)
if form.is_valid():
# Do something here to process and save the form data
form.save()
else:
print(form.errors)
else:
form = ContactForm()
return render(request, 'contact_form.html', {'form': form})
Now, within your html template, you could just replace the respective input fields with the form object fields. For example:
<form method="POST" ...>
# Where you have these fields
<input type="text" id="contact_name" name="contact_name" class="form-control form-control-lg-border-0" placeholder = "Your Name"/>
# Just replace with... (i.e.: contact_name as above)
{{ form.contact_name }}
# Apply the above with the other respective fields.
</form>
I trust you already know how to set up your url for the view. In a nutshell, that's an approach you could take.
I do recommend that you read the doc for more information on the Django forms though.
Related
I have created a new table using models.py and this table stores data to my models.py table which I created.
Now when I am going to my login page its not able to authenticate the details from that table and always gives invalid credentials.
My app name which I created is User and the table name which is stored in SQLite is User_register
Login.html
<div class="wrapper gradient">
<div class="container">
<div class="row centered-form">
<div class="col-xs-12 col-sm-8 col-md-4 col-sm-offset-2 col-md-offset-4">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title"><center><b>Login To Web App!!</b></center> </h3>
</div>
<div class="panel-body">
<form role="form" method="POST">
{% csrf_token %}
<div class="form-group">
<input type="text" name="email" id="email" class="form-control input-sm" placeholder="Username">
</div>
<div class="form-group">
<input type="password" name="password" id="password" class="form-control input-sm" placeholder="Password">
</div>
<div class="form-group">
{% for message in messages %}
<p style="color:black;">{{message}}</p>
{% endfor %}
</div>
<input type="submit" value="Login" class="btn btn-info btn-block">
</form>
</div>
</div>
</div>
</div>
</div>
</div>
Models.py
class Register(models.Model):
first_name = models.CharField(max_length=90)
last_name = models.CharField(max_length=90)
email = models.EmailField(max_length=90)
password = models.CharField(max_length=90)
Views.py
def login(request):
if request.method == 'POST':
email = request.POST['email']
password = request.POST['password']
user = auth.authenticate(email=email, password=password)
if user is not None:
auth.login(request, user)
return render(request,'index.html')
else:
messages.info(request, 'Invalid credentials')
return render(request,'login.html')
else:
return render(request, 'login.html')
I may be out of touch, but
the fields youre using are premade in the standard auth backend which you easily set to use those fields. A good tutorial for this is apart of this youtube series https://youtube.com/playlist?list=PLzMcBGfZo4-kQkZp-j9PNyKq7Yw5VYjq9
Or check out a extended example with password reset etc in the register app of this repo https://github.com/HarryLudemann/Job-Search
If you still require making your own custom model i suggest you using a 'custom authbackend' this is nearly always the way togo unless you use the prebuild form check it ou here https://docs.djangoproject.com/en/3.2/topics/auth/customizing/
If You still want to use the setuo youre using you should be using the built in forms, this allows you to use the cleaned_data method check out the docs https://docs.djangoproject.com/en/3.2/ref/forms/fields/
Or look for a example in the github repo above.
If this does not answer help please post any more code, errors or info you have. Also ensure you have run the makemigrations and migrate aswell as mugrate your server setup. Hope this somewhat helps 👍
I'm trying to add some data to the DB from a modal form in django. After filling all the fields and click on submit it doesn't save on the DB. Here are the models, views and forms and the template. I think the problem it's on the views.py
models.py
class Buyer(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
name = models.CharField(max_length=255)
phone_numbers = ArrayField(PhoneNumberField())
industry = models.IntegerField(null=True)
credit_limit = MoneyField(max_digits=20, decimal_places=2,
default_currency='MMK', null=True)
is_active = models.BooleanField(default=True)
datetime_created = models.DateTimeField(auto_now_add=True)
datetime_updated = models.DateTimeField(auto_now=True)
views.py
class BuyerCreateView(AtomicMixin, View):
template_name = 'add_buyer_modal.html'
def get(self, request):
form = BuyerForm()
return render(request, self.template_name, {'form': form})
def post(self, request):
form = BuyerForm(request.POST)
if form.is_valid():
form.save()
messages.success(request, 'Buyer created!', extra_tags='alert alert-success')
return HttpResponseRedirect(self.request.META.get('HTTP_REFERER'))
messages.error(request, 'Unable create buyer. {}'.format(form.errors), extra_tags='alert alert-danger')
return HttpResponseRedirect(self.request.META.get('HTTP_REFERER'))
forms.py
class BuyerForm(forms.ModelForm):
class Meta:
model = Buyer
fields = ['name', 'phone_numbers', 'industry', 'credit_limit']
template
<div class="modal fade" id="add-buyer-modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">New Buyer</h5>
<button type="button" data-dismiss="modal" aria-label="Close" class="close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="col-md-12 modal-body">
<form id="buyer-form" method="post" class="submit-form" action="{% url 'buyers:add_buyer' %}">
{% csrf_token %}
<div class="col-md-12">
<div class="form-group label-floating">
<label class="control-label">Name</label>
<input autocomplete="false" type="text" name="name" class="form-control" required>
</div>
</div>
<div class="col-md-12">
<div class="form-group label-floating">
<label class="control-label">Industry</label>
<div class="input-group">
<input autocomplete="false" type="number" name="industry" class="form-control" required>
</div>
</div>
</div>
<input id="payment-submit" type="submit" class="btn btn-primary pull-right submit-button" />
</form>
</div>
</div>
</div>
urls.py
urlpatterns = [
url(r'^$', buyers_views.BuyerListView.as_view(), name='buyers_list'),
url(r'^(?P<id>[0-9a-f-]+)/$',
buyers_views.BuyerDetailView.as_view(), name='buyers_detail'),
url(r'^/buyer/add/', buyers_views.BuyerCreateView.as_view(), name='add_buyer'),
]
Check to see if your form is invalid. You only fill out 2 of the 3 fields in the HTML form and send it back to the server. Therefore, when you check to see if the form.is_valid(), it's probably returning False and therefore, not actually saving the form.
To check, you can put a print statement inside the if statement printing out 'success' and one after the if statement printing out 'failure'. If you don't see the 'success' print out, it means your form is invalid.
If this truly is the issue, add form fields in the HTML for all fields in your form. Any field you include in the fields attribute of a form by default is required. This means that if the field isn't filled out when calling is_valid on the form, a validation error for that field will be thrown.
I'm using different forms (POST and GET) in my Django web application and Bootstrap modal to do that.
In my template, user can choose some documents, submit the list of documents which is picked up to a Django form (CustomerForm) in my modal. This CustomerForm lets to send an email with user informations previously filled.
My CustomerForm looks like this :
class CustomerForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(CustomerForm, self).__init__(*args, **kwargs)
self.fields['country'].empty_label = _('Select a country')
self.fields['country'].queryset = self.fields['country'].queryset.order_by('name')
self.fields['email'].required = True
self.fields['first_name'].required = True
self.fields['last_name'].required = True
self.fields['country'].required = True
self.fields['institution'].required = False
class Meta:
model = Customer
fields = ['email', 'first_name', 'last_name', 'country', 'institution']
widgets = {
'email': forms.TextInput(attrs={'placeholder': _('name#example.com')}),
'first_name': forms.TextInput(attrs={'placeholder': _('First Name')}),
'last_name': forms.TextInput(attrs={'placeholder': _('Last Name')}),
'institution': forms.TextInput(attrs={'placeholder': _('Agency, company, academic or other affiliation')}),
}
I have views.py file :
class HomeView(CreateView, FormView):
""" Render the home page """
template_name = 'index.html'
form_class = CustomerForm
def get_context_data(self, **kwargs):
# display some things
# ...
if "DocumentSelected" in self.request.GET:
checkbox_list = self.request.GET.getlist('DocumentChoice')
document = Document.objects.filter(id__in=checkbox_list)
kwargs['selected_document'] = document
return super(HomeView, self).get_context_data(**kwargs)
def form_valid(self, form):
email = form.cleaned_data['email']
country = form.cleaned_data['country']
for checkbox in self.request.GET.getlist('DocumentChoice'):
document = Document.objects.get(id=checkbox)
token = self.gen_token(email)
now = timezone.now()
expiration = now + settings.DOWNLOAD_VALIDITY
Download.objects.create(email=email, country=country, doc_id=checkbox, token=token,
expiration_date=expiration)
self.send_email(email, document.upload, document.publication.title, token)
return super(HomeView, self).form_valid(form)
And finally in my HTML template you can find something which looks like this :
<form method="GET" action="">
<!-- Table with checkboxes - User has to check wanted objects -->
<div class="row">
<div class="col-md-offset-3 col-md-4">
<input type="submit" class="btn btn-default" name="DocumentSelected" value="{% trans 'Save document(s)' %}"/>
<input type="button" class="btn btn-default" data-toggle="modal" data-target="#myModal" value="{% trans 'Send document(s)' %}"/>
</div>
</div>
</form>
<!-- Modal -->
<div class="modal fade" id="myModal" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">{% trans 'Your informations' %}</h4>
</div>
<form method="post" action="" novalidate>
{% csrf_token %}
<div class="modal-body">
<div class="row">
<div class="col-md-12">
{{ form.email|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-6">
{{ form.first_name|as_crispy_field }}
</div>
<div class="col-md-6">
{{ form.last_name|as_crispy_field }}
</div>
</div>
<div class="row">
<div class="col-md-6">
{{ form.country|as_crispy_field }}
</div>
<div class="col-md-6">
{{ form.institution|as_crispy_field }}
</div>
</div>
</div>
<div class="modal-header">
<h4 class="modal-title">{% trans 'Your cart' %}</h4>
</div>
<div class="model-body">
{% for element in selected_document|dictsort:'format' %}
<!-- Display wanted objects -->
{% endfor %}
</div>
<div class="modal-footer">
<input type="submit" class="btn btn-default" data-dismiss="modal" value="{% trans 'Send' %}"/>
</div>
</form>
</div>
</div>
</div>
Process :
This is the needed way :
User has to check one or multiple documents
User submits the choice and a modal containing CustomerForm is opening.
User fills CustomerForm fields and see in Cart part his document(s)
User submits the CustomerForm and an email is sent with previous informations/documents.
I think my method could work, but I don't overcome to call form_valid function and I would like to write correctly this class.
There is certainly ugly issues and I apologize by advance. But this is not the best way to improve myself and doesn't reproduce these issues ? ;)
Thanks !
EDIT :
I made something which seems to work. I removed data-dismiss="modal" from my modal submit button. I read that this attribute closed my modal and didn't post any form !
Finally, is it a good way to do what I did ?
Is it possible to replace both buttons Save documents and Send documents by an unique button which get documents and open the modal ?
I made something which seems to work. I removed data-dismiss="modal" from my modal submit button.
Previously :
<input type="submit" class="btn btn-default" data-dismiss="modal" value="{% trans 'Send' %}"/>
Now :
<input type="submit" class="btn btn-default" value="{% trans 'Send' %}"/>
It works now !
It was because data-dismiss="modal" closed the modal and I didn't know that.
Hi i just have a small doubt can we create a HTML template which will have the Django form and normal HTML form together.
I created a HTML template which has both normal HTML input tag and Django forms.
I am getting the following error when i do a form.save(commit=False)
could not be created because the data didn't validate.
My view.py
if request.method == 'POST':
form_value = request.POST.copy()
print form_value
form = InfoForm(data=request.POST)
post_val = form.save(commit=False)
my HTML
<div class="form-row">
<div class="form-group col-md-4">
{{form.name}}
</div>
<div class="form-group col-md-4">
{{form.number}}
</div>
<div class="form-group col-md-4">
{{form.location}}
</div>
</div>
<div class="form-group">
<label for="Feedback">Feedback</label>
<div id="Feedback" class="optionBox1">
<div class="input-group my-add-div">
<input type="text" class="form-control" name="feedback" required>
<input type="text" class="form-control" name="feedback" required>
<input type="text" class="form-control" name="feedback" required>
</div>
</div>
</div>
my form.py
class InfoForm(forms.ModelForm):
name = forms.CharField(label='Project Name',max_length=100,widget=forms.TextInput(attrs={'class':'form-control','placeholder':'Click to enter text',}))
number = forms.DecimalField(label='Project #',widget=forms.NumberInput(attrs={'class':'form-control','placeholder':'Enter the ID',}))
location = forms.CharField(label='Location',max_length=100,widget=forms.TextInput(attrs={'class':'form-control','placeholder':'Enter the Location',}))
class Meta:
model = Info
field = ('name','number','location',)
My Model.py
name = models.CharField(max_length=200,blank=True , null=True)
number = models.IntegerField(blank=True , null=True)
location = models.CharField(max_length=200,blank=True , null=True)
feedback = ArrayField(ArrayField(models.CharField(max_length=200,blank=True,null=True)))
Thanks in advance
You need to first call form.is_valid() to use save method on the form.
All what you need to create any form in template you want, example:
``
<form action="." method="post">
{% csrf_token %}
<input type="text" name="first_name">
<p><input type='submit' value="Change"></p>
</form> ``
then, in your view call
first_name = request.POST['first_name']
and it will be works fine.
I am trying to pass data from my website's login page as a POST request to Flask. However, Flask fails to obtain any data. Here's a code snippet of my test.py file that runs the Flask app. I realised that the code isn't entering the method itself.Can anyone help me understand where am I going wrong?
#app.route('/', methods=['POST'])
def my_form_post():
text = request.form['text']
processed_text = text.upper()
print "Processed text is..."
print processed_text
return processed_text
Here's the snippet of my login form:
div class="modal fade" id="direct-login-form" tabindex="-1" role="dialog" aria-labelledby="direct-login-form-label" aria-hidden="true">
<div class="vertical-alignment-helper">
<div class="modal-dialog vertical-align-center">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span>
</button>
<h4 class="modal-title" id="direct-login-form-label">Login</h4>
</div>
<div class="modal-body">
<div class="wrap-login-form wrap-reviews">
<form id="direct-login" form action="." method="POST" class="form-horizontal">
<div class="form-group">
<label class="col-sm-3" for="direct_username">Username</label>
<div class="col-sm-9">
<input type="text" name="text" class="form-control" id="direct_username" placeholder="Username">
</div>
</div>
<div class="form-group">
<label class="col-sm-3" for="direct_password">Password</label>
<div class="col-sm-9">
<input type="password" class="form-control" id="direct_password" placeholder="Password">
</div>
</div>
<div class="wrap-slidecheck clearfix">
<div class="col-sm-3"></div>
<div class="col-sm-9">
<div class="slidecheck">
<input type="checkbox" id="direct_remember_me" name="check" />
<label for="direct_remember_me"></label>
</div>
<span>Remember me</span>
</div>
</div>
<div class="form-group">
<label class="col-sm-3"></label>
<div class="col-sm-9">
<button type="submit" name="my-form" class="btn btn-default" value="Send">Submit</button>
</div>
</div>
<div class="form-group">
<label class="col-sm-3"></label>
<div class="col-sm-9">
<p class="help-block">Lost your password?<span> or </span>Register an Account</p>
</div>
</div>
<input type="hidden" id="direct_security" name="direct_security" value="f0abedaf74" /><input type="hidden" name="_wp_http_referer" value="/directory-category/coffee-lounge/" /> </form>
</div>
</div>
</div>
</div>
</div>
</div>
I simulated your problem on my machine it worked !
I made the following changes.
for view
#app.route("/")
def hello():
return render_template('register.html')
#app.route("/register", methods=['POST'])
def register():
text = request.form['text']
passwd = request.form['passwd']
processed_text = text.upper()
print "Processed text is...", processed_text, passwd
#do your further processing like saving to Database...
return render_template('register.html') #send to the profile/dashboard page
for html file
<form id="direct-login" form action="{{ url_for('register') }}" method="POST" class="form-horizontal">
<input type="password" class="form-control" id="direct_password" name='passwd' placeholder="Password">
However you should use WTF forms you will have a clean and reusable code with that.
an example forms.py
class RegistrationForm(Form):
email = StringField('Email', validators=[Required(), Email(), Length(1, 64)])
username = StringField('Username', validators=[Required(), Length(1, 64), Regexp('^[A-Za-z][A-za-z0-9._]*$', 0,'Username must have only letters, dots, digitsm or underscores')])
password = PasswordField('Password', validators=[Required(), EqualTo('password2', message='Password must match.')])
password2 = PasswordField('Confirm Password', validators=[Required()])
submit = SubmitField('Register')
'''
Custome validator for email validate_*
'''
def validate_email(self, field):
if(User.query.filter_by(email= field.data)).first():
raise ValidationError('Email already registered.')
'''
Custome validator for email validate_*
'''
def validate_username(self, field):
if(User.query.filter_by(username = field.data)).first():
raise ValidationError('Username already registered.')
then your html becomes
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %} - Register{% endblock %}
{% block page_content %}
<div class="page-header">
<h1>Register</h1>
</div>
<div class="col-md-5">
{{ wtf.quick_form(form) }}
</div>
{% endblock %}
The line containing the opening tag for your form seems like the suspect here:
<form id="direct-login" form action="." method="POST" class="form-horizontal">
While I'm not sure if the floating form attribute is causing any issues, I'm certain that it isn't doing anything useful so you should get rid of that.
Also, by specifying action=".", you are saying that the submission of the form should be directed to the same route that you got the form from. In your Flask code, you wrote
#app.route('/', methods=["POST"])
so in your form tag, you should specify action="/" for the submission to go to the my_form_post method in Flask.