How to assign HTML Form fields to DJANGO Model Forms without using ModelForm - django

I am trying to make pretty looking HTML form where each fields are formatted with some validation and icons. Once these fields are submitted I want to save to Model instance using either using Model form or some other approach which allows to make this operation smooth.
Here is my code snippet:
model.py:
class Client(Model):
client_id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
first_name = models.CharField(max_length=256)
last_name = models.CharField(max_length=256)
date_of_birth = models.DateField(blank=True, null=True)
email = models.EmailField(null=True)
form.py:
class ClientNewForm(forms.ModelForm):
class Meta:
model = Client
fields = "__all__"
view.py (I know this is wrong but need help to figure out what's the best way to do this):
class ClientCreateView(CreateView):
model=Client
form_class = ClientNewForm
template_name = 'Client/client_new.html'
context_object_name = 'client' # refer the object as patient in template
success_url = reverse_lazy('WebApp:clients')
def form_valid(self, form):
model = form.save(commit=False)
#model.submitted_by = self.request.user
model.save()
messages.success(self.request, "The Client is created successfully.")
return super(ClientCreateView, self).form_valid(form)
Template:
<div class='row'>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="x_panel">
<div class="x_title">
<h2>NEW REGISTRATION</h2>
</div>
<div class="x_content">
<form class="form-horizontal form-label-left input_mask" action="" method="post">
{% csrf_token %}
<div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
<input type="text" class="form-control has-feedback-left" id="in-fn" placeholder="First Name" name="first_name">
<span class="fa fa-user form-control-feedback left" aria-hidden="true"></span>
</div>
<div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
<input type="text" class="form-control has-feedback-left" id="in-ln" placeholder="Last Name" name="last_name">
<span class="fa fa-user form-control-feedback left" aria-hidden="true"></span>
</div>
<div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
<input type="text" class="form-control has-feedback-left" id="in-dob" name="date_of_birth" placeholder="Date of Birth (mm/dd/yyyy)" >
<span class="fa fa-calendar form-control-feedback left" aria-hidden="true"></span>
</div>
<div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
<input type="text" class="form-control has-feedback-left" id="in-email" placeholder="Email" name="email">
<span class="fa fa-envelope form-control-feedback left" aria-hidden="true"></span>
</div>
<div class="form-buttons">
<div class="col-md-9 col-sm-9 col-xs-12 col-md-offset-9">
Cancel
Reset
<input type="submit" value="Save" class="btn btn-round btn-success"/>
</div>
</div>
</form>
</div>
</div>
</div>
So I need help from Django Experts to make this work properly. If possible can you please help me to figure out following:
Can I make each Django Field as individual formatting filed (I like to format each fields better than crispy forms)? (I am using gentelella templates).
What would be best way to get each fields assign back to model fields and save in database? Current approach I am taking is Django Model form but I am not sure if this right approach for me to achieve what I am trying to do.
Really appreciate your help and consideration.
Thank You.

I used django-wiget-tweaks library to get me through this problem.
Its super Easy and it works like charm to help me customize the form look and feel.
Here are steps I followed:
step 1: install: pip install django-widget-tweaks on my virtual environment
Step 2: update settings.py for INSTALLED_APPS = [ 'widget_tweaks']
Step 3: on my template I had to put following at the top of the Template:
{% load widget_tweaks %}
Step 4: Now I can use the renderfields to do this all stuff as follow:
<div class='row'>
<div class="col-md-8 col-sm-8 col-xs-12">
<div class="x_panel">
<div class="x_title">
<h2>NEW REGISTRATION</h2>
</div>
<div class="x_content">
<form class="form-horizontal form-label-left input_mask" action="" method="post">
{% csrf_token %}
<div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
{% render_field form.first_name class="form-control" placeholder="First Name"|append_attr:"required" %}
<span class="fa fa-user form-control-feedback left" aria-hidden="true"></span>
</div>
<div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
{% render_field form.last_name class="form-control" placeholder="Last Name" %}
<span class="fa fa-user form-control-feedback left" aria-hidden="true"></span>
</div>
<div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
{% render_field form.date_of_birth class="form-control" placeholder="Date of Birth (mm/dd/yyyy)"%}
<span class="fa fa-calendar form-control-feedback left" aria-hidden="true"></span>
</div>
<div class="col-md-6 col-sm-6 col-xs-12 form-group has-feedback">
{% render_field form.email class="form-control has-feedback-left" placeholder="Email Address" %}
<span class="fa fa-envelope form-control-feedback left" aria-hidden="true"></span>
</div>
<div class="form-buttons">
<div class="col-md-9 col-sm-9 col-xs-12 col-md-offset-9">
Cancel
Reset
<input type="submit" value="Save" class="btn btn-round btn-success"/>
</div>
</div>
</form>
</div>
</div>
</div>
Step 5: On view now I can use CreateView, UpdateView, ListView with Modelforms.
So far it works for me.
I hope this helps to other member who is looking to be creative with their forms.

Related

How to render error or validation messages to ModelForm in 2022

I've spent several hours researching on the internet, especially the official Django documentation, but still it is not clear to me which is the best option in 2022 (since almost all questions I read on SO are > 6 yo)
and there are diverse opinions on whether crispy forms is better or not.
Is still crispy forms a recommended option?
How can I (and what is the most recommended way to) get the typical validation error messages?
Like: "this field is mandatory" or "this input accepts numbers only"? I've seen some Django pages using those default messages but I don't know how to show them in my ModelForm fields.
Lets say I have the following model:
class Project(models.Model):
project_name = models.CharField(max_length=250, null=False, blank=False)
status = models.CharField(
max_length=250,
null=True,
blank=True,
default=PROJECT_STATUS_DEFAULT,
choices=PROJECT_STATUS,
)
creation_date = models.DateField(max_length=250, null=False, blank=False)
project_code = models.IntegerField(null=True, blank=True)
notes = models.CharField(max_length=250, null=True, blank=True)
And for the Project model I have the following ModelForm:
class CreateNewProjectForm(ModelForm):
creation_date = forms.DateField(widget=forms.DateInput(format = '%d/%m/%Y'), input_formats=settings.DATE_INPUT_FORMATS) #UK Date format
class Meta:
model = Project
fields = '__all__'
The view, when I try to create a new object Project:
def add_new_project(request):
context = {}
if request.method == 'POST':
form = CreateNewProjectForm(request.POST)
if form.is_valid():
form.save()
return redirect('project_page')
else:
print (form.errors)
form = CreateNewProjectForm()
context['form'] = form
return render(request, 'new_project.html', context)
HTML part:
<div class="card h-100">
<div class="card-header project-page-header">
<h3>Create A New Project</h3>
</div>
<div class="card-body px-0 new-project-card-body">
<div class="cardItem">
<div class="row">
<div class="col">
<div class="row">
<div class="tab-pane fade show active" id="general">
<form id="newProjectForm" method="POST" action="new_project">
{% csrf_token %}
<div class="accordion accordion-flush" id="accordionGeneral">
<div class="accordion-item">
<h2 class="accordion-header" id="general-headingOne">
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#general-collapseOne" aria-expanded="false" aria-controls="general-collapseOne">
Details
</button>
</h2>
<div id="general-collapseOne" class="accordion-collapse collapse show" aria-labelledby="general-headingOne" data-bs-parent="#accordionGeneral">
<div class="accordion-body">
<div class="row">
<div class="col-5">
<ul class="list-unstyled">
<li class="mt-3">
<div class="row">
<div class="col-sm ph-tabs-field-label">
Project Name
</div>
<div class="col-sm">
<input type="text" name="project_name" class="form-control" aria-label="Project Name">
</div>
</div>
</li>
<li class="mt-3">
<div class="row">
<div class="col-sm ph-tabs-field-label">
Status
</div>
<div class="col-sm">
<select name="status" class="selectpicker show-tick w-100" aria-label="Status">
{% for status in project_status %}
{% if forloop.first %}
<option value="{{ status.id }}" selected>{{ status.text }}</option>
{% else %}
<option value="{{ status.id }}">{{ status.text }}</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
</li>
<li class="mt-3">
<div class="row">
<div class="col-sm ph-tabs-field-label">
Creation Date
</div>
<div class="col-sm">
<input type="text" name="creation_date" class="form-control">
</div>
</div>
</li>
<li class="mt-3">
<div class="row">
<div class="col-sm ph-tabs-field-label">
Project Code
</div>
<div class="col-sm">
<input type="text" name="project_code" class="form-control">
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<div class="accordion-item">
<h2 class="accordion-header" id="general-headingThree">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#general-collapseThree" aria-expanded="false" aria-controls="general-collapseThree">
Note
</button>
</h2>
<div id="general-collapseThree" class="accordion-collapse collapse" aria-labelledby="general-headingThree" data-bs-parent="#accordionGeneral">
<div class="accordion-body"><textarea name="notes" class="form-control" rows="7"></textarea></div>
</div>
</div>
<button type="submit" id="projectEditBtn" form="newProjectForm" class="btn btn-info rounded-0">Save</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
I saw solutions like this, but the problem is that my form fields are spread over different accordions, I can't use something like {% if form.errors %}, I need something more specific for each field.
First update your views like this
def add_new_project(request):
context = {}
if request.method == 'POST':
form = CreateNewProjectForm(request.POST)
if form.is_valid():
form.save()
return redirect('project_page')
else:
print (form.errors)
context['form'] = form
return render(request, 'new_project.html', context)
context['form'] = CreateNewProjectForm()
return render(request, 'new_project.html', context)
You can specify error for each field like this
{% if form.field_name.errors %}
{{ form.field_name.errors }}
{% endif %}

How is it possible to get data from one form that has multiple textareas in Django

I'd like to get data from one form that has multiple textareas inside , In my views: 'compare_ingredients' I've tried requesting data from my form id 'compareform' also the textarea id 'ingredients', but when I enter something into one texture and click on submit it comes back as 'None' when I print. Here is my html and views:
html :
<div class="container-fluid">
<h4>Please enter in your ingredients:</h4>
<h6>(Seperate each item by comma)</h6>
<br>
<button class="add_item">Add Item</button>
<br>
<div class="row row-cols-1 row-cols-md-2 mx-auto">
<form action="{% url 'compare_ingredients' %}" method="POST" name="compareform" id="compare">
{% csrf_token %}
<br>
<button type="submit" class="btn btn-info sub_btn">Submit</button>
<button type="submit" class="btn btn-secondary back_button">
Back
</button>
<br>
<br>
<div class="row form_row">
<div class="col mb-4">
<h5>Item 1</h5>
<div class="card form_card">
<div class="card-body compare_cardbody">
<textarea name="ingredients1" id="ingredients" cols="30" rows="10" form="compareform"></textarea>
</div>
</div>
</div>
<div class="col mb-4">
<h5>Item 2</h5>
<div class="card form_card">
<div class="card-body compare_cardbody">
<textarea name="ingredients2" id="ingredients" cols="30" rows="10" form="compareform"></textarea>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
views.py:
def compare_ingredients(request):
if request.method == "POST":
ingredients = request.POST.get('compareform')
print(ingredients)
return render(request, 'result/compare.html')
ok, I figured it out , the problem was in the html textarea I had the name of the form as 'compareform' when it should have been 'compare' :
<textarea name="ingredients2" id="ingredients" cols="30" rows="10" form="compare"></textarea>
then in my views I did:
ingredients1 = request.POST.get('ingredients1')

Django and Bootstrap Modal

Please help me to progress with my project. I'm new to Django and bootstrap and i'm currently working on a project. For the Registration of the user i'm using a popup modal.
I've set up the following:
Html file with modal
{% load static %}
<!-- Register Modal Starts -->
<div class="row mt25 tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
<div class="col-lg-6 col-xl-6">
<div class="regstr_thumb">
<img class="img-fluid w100" src="{% static 'images/resource/regstr.jpg' %}" alt="regstr.jpg">
</div>
</div>
<div class="col-lg-6 col-xl-6">
<div class="sign_up_form">
<form action="{% url 'register' %}" method="POST" id="register-form">
{% csrf_token %}
<div class="heading">
<h4>Register</h4>
</div>
<div class="row">
<div class="col-lg-12">
<button type="submit" class="btn btn-block btn-fb"><i class="fa fa-facebook float-left mt5"></i> Login with Facebook</button>
</div>
<div class="col-lg-12">
<button type="submit" class="btn btn-block btn-googl"><i class="fa fa-google float-left mt5"></i> Login with Google</button>
</div>
</div>
<hr>
<div class="form-group ui_kit_select_search mb0">
<select class="selectpicker" data-live-search="true" data-width="100%">
<option data-tokens="SelectRole">Landlord</option>
<option data-tokens="Agent/Agency">Property Manager</option>
<option data-tokens="SingleUser">Homeowner</option>
</select>
</div>
<div class="form-group input-group">
<p>{{ form.errors.email}}</p>
{{form.email}}
<input type="email" class="form-control" id="exampleInputEmai" placeholder="Email">
<div class="input-group-prepend">
<div class="input-group-text"><i class="fa fa-envelope-o"></i></div>
</div>
</div>
<div class="form-group input-group">
<p>{{ form.errors.password1 }}</p>
{{ form.password1 }}
<input type="password" name="password1" class="form-control" id="exampleInputPassword2" placeholder="Password">
<div class="input-group-prepend">
<div class="input-group-text"><i class="flaticon-password"></i></div>
</div>
</div>
<div class="form-group input-group">
<p>{{ form.errors.password2 }}</p>
{{ form.password2 }}
<input type="password" name="password2" class="form-control" id="exampleInputPassword3" placeholder="Re-enter password">
<div class="input-group-prepend">
<div class="input-group-text"><i class="flaticon-password"></i></div>
</div>
</div>
<div class="form-group input-group">
<p>{{ form.errors.country }}</p>
{{ form.country }}
<input type="country" name="country" class="form-control" id="exampleInputCountry" placeholder="Country">
<div class="input-group-prepend">
<div class="input-group-text"><i class="flaticon-country"></i></div>
</div>
</div>
<div class="form-group input-group">
<p>{{ form.errors.city }}</p>
{{ form.city }}
<input type="city" name="city" class="form-control" id="exampleInputCity" placeholder="City">
<div class="input-group-prepend">
<div class="input-group-text"><i class="flaticon-city"></i></div>
</div>
</div>
<div class="form-group input-group">
<p>{{ form.errors.phone_number }}</p>
{{ form.phone_number }}
<input type="phone" name="phone_number" class="form-control" id="exampleInputPhone" placeholder="Phone Number">
<div class="input-group-prepend">
<div class="input-group-text"><i class="flaticon-phone"></i></div>
</div>
</div>
<div class="form-group custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="exampleCheck2">
<label class="custom-control-label" for="exampleCheck2">I have read and accept the Terms and Privacy Policy?</label>
</div>
<button type="submit" class="btn btn-log btn-block btn-thm">Sign Up</button>
<p class="text-center">Already have an account? <a class="text-thm" href="#">Log In</a></p>
</form>
</div>
</div>
</div>
The views.py file:
from django.shortcuts import render, redirect
from .forms import UserAdminCreationForm
from django.contrib import messages
def login(request):
return render(request, 'login.html')
def register(request):
form = UserAdminCreationForm()
if request.method == 'POST':
form = UserAdminCreationForm(request.POST)
if form.is_valid():
form.save()
user = form.cleaned_data.get('email')
messages.success(request, 'Account was created for ' + user)
return redirect('index')
return render(request, 'accounts/register.html', {'form': form})
The urls.py file
from django.urls import path, include
from . import views
urlpatterns = [
path('accounts/', include('django.contrib.auth.urls')),
path('register', views.register, name='register'),
path('logout', views.logout, name='logout'),
path('dashboard', views.dashboard, name='dashboard'),
]
The forms.py file:
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm
from django import forms
class UserAdminCreationForm(UserCreationForm):
"""A Custom form for creating new users."""
email = forms.EmailField(label="", widget=forms.EmailInput(attrs={'class': 'form-control', 'placeholder': 'Email Address'}), )
password1 = forms.CharField(label="", widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Password'}))
password2 = forms.CharField(label="", widget=forms.PasswordInput(attrs={'class': 'form-control', 'placeholder': 'Repeat Password'}))
country = forms.CharField(label="", max_length=50, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Country'}))
city = forms.CharField(label="", max_length=50, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'City'}))
phone_number = forms.CharField(label="", max_length=20, widget=forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Phone Number'}))
class Meta:
model = get_user_model()
fields = ['user_types', 'email', 'password1', 'password2', 'country', 'city', 'phone_number']
When the popup modal with the registration form is opened and click SignUp i have setup a new page accounts/register page just for testing. But i do not want this page, i want to complete the form above and add user in the database. How can i configure that?
My problems that i cannot solve are:
how when i fill in the popup registration (inside the modal) and press SignUp to add user in the database without the accounts/register page?
Please help! Thank you for your time!
change input fields with form.{field name} and add {{ form.errors.{fieldname} }}
here your code:
<!-- Login/Register Starts -->
<!-- Modal -->
<div class="sign_up_modal modal fade" tabindex="-1" role="dialog" aria-hidden="true" id=bd-example-modal-lg>
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
</div>
<div class="modal-body container pb20">
<div class="row">
<div class="col-lg-12">
<ul class="sign_up_tab nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Login</a>
</li>
<li class="nav-item">
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Register</a>
</li>
</ul>
</div>
</div>
<!-- Register Modal Starts -->
<div class="row mt25 tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">
<div class="col-lg-6 col-xl-6">
<div class="regstr_thumb">
<img class="img-fluid w100" src="{% static 'images/resource/regstr.jpg' %}" alt="regstr.jpg">
</div>
</div>
<div class="col-lg-6 col-xl-6">
<div class="sign_up_form">
<form action="{% url 'register' %}" method="POST" id="register-form">
{% csrf_token %}
{{form.as_p}}
<div class="heading">
<h4>Register</h4>
</div>
<div class="row">
<div class="col-lg-12">
<button type="submit" class="btn btn-block btn-fb"><i class="fa fa-facebook float-left mt5"></i> Login with Facebook</button>
</div>
<div class="col-lg-12">
<button type="submit" class="btn btn-block btn-googl"><i class="fa fa-google float-left mt5"></i> Login with Google</button>
</div>
</div>
<hr>
<div class="form-group ui_kit_select_search mb0">
<select class="selectpicker" data-live-search="true" data-width="100%">
<option data-tokens="SelectRole">Landlord</option>
<option data-tokens="Agent/Agency">Property Manager</option>
<option data-tokens="SingleUser">Homeowner</option>
</select>
</div>
<div class="form-group input-group">
<p>{{ form.errors.email}}</p>
{{ form.email }}
<div class="input-group-prepend">
<div class="input-group-text"><i class="fa fa-envelope-o"></i></div>
</div>
</div>
<div class="form-group input-group">
<p>{{ form.errors.password1 }}</p>
{{ form.password1 }}
<div class="input-group-prepend">
<div class="input-group-text"><i class="flaticon-password"></i></div>
</div>
</div>
<div class="form-group input-group">
{{ form.password2 }}
<div class="input-group-prepend">
<div class="input-group-text"><i class="flaticon-password"></i></div>
</div>
</div>
<div class="form-group input-group">
<p>{{ form.errors.country }}</p>
{{ form.country }}
<div class="input-group-prepend">
<div class="input-group-text"><i class="flaticon-country"></i></div>
</div>
</div>
<div class="form-group input-group">
<p>{{ form.errors.city }}</p>
{{ form.city }}
<div class="input-group-prepend">
<div class="input-group-text"><i class="flaticon-city"></i></div>
</div>
</div>
<div class="form-group input-group">
<p>{{ form.phone_number }}</p>
{{ form.phone_number }}
<div class="input-group-prepend">
<div class="input-group-text"><i class="flaticon-phone"></i></div>
</div>
</div>
<div class="form-group custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="exampleCheck2">
<label class="custom-control-label" for="exampleCheck2">I have read and accept the Terms and Privacy Policy?</label>
</div>
<button type="submit" class="btn btn-log btn-block btn-thm">Sign Up</button>
<p class="text-center">Already have an account? <a class="text-thm" href="#">Log In</a></p>
</form>
</div>
</div>
</div>

Django forms using html elements with different name from moels field

In my django project i have this model:
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE,)
u_fullname = models.CharField(max_length=200)
u_email = models.EmailField()
u_profile = models.CharField(max_length=1)
u_job = models.CharField(max_length=100, null=True, blank=True, default='D')
u_country = models.CharField(max_length=20, null=True, blank=True, default='Italy')
u_regdata = models.DateTimeField(auto_now=True)
stripe_id = models.CharField(max_length=100, null=True, blank=True)
activation_code = models.CharField(max_length=10)
u_picture = models.ImageField(upload_to='profile_images', blank=True)
u_active = models.BooleanField(default=False)
u_terms = models.BooleanField(default=False)
def __unicode__(self):
return self.u_profile
and a forms.py like this one:
from a_profile.models import UserProfile
class ProfileModelForm(ModelForm):
class Meta:
model = UserProfile
fields = ['u_fullname',
'u_job',
'u_country',
'u_email',
'u_terms',
]
def clean(self):
cleaned_data = super(ProfileModelForm, self).clean()
u_fullname = cleaned_data.get('u_fullname')
u_job = cleaned_data.get('u_job')
u_country = cleaned_data.get('u_country')
u_email = cleaned_data.get('u_email')
u_terms = cleaned_data.get('u_terms')
if not u_terms:
raise forms.ValidationError("Please read and accept our Terms of Service")
if not u_fullname and not u_job and not u_country and not u_terms:
raise forms.ValidationError('You have to write something!')
return cleaned_data
well, now in html i have to use different names for element related to form fields:
<form action="" method="POST">
{% csrf_token %}
{{ form.errors }}
<div class="row">
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="text" name="u_fullname_C" id="u_fullname_c"
placeholder="Company Name">
<i class="la la-building"></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<select name="u_country_c" id="u_country_c"
value="{{ form.u_country }}">
<option selected="selected">Italy</option>
<option>Spain</option>
<option>USA</option>
<option>France</option>
</select>
<i class="la la-globe"></i>
<span><i class="fa fa-ellipsis-h"></i></span>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<select name="u_job_c" id="u_job_c" value="{{ form.u_job }}">
<option selected="selected">Technology</option>
<option>Healthcare</option>
<option>Building</option>
<option>Aerospace</option>
</select>
<i class="la la-industry"></i>
<span><i class="fa fa-ellipsis-h"></i></span>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="text" name="u_email_c" id="u_email_c"
placeholder="Enter a valid email"
value="{{ form.u_email }}">
<i class="la la-envelope"></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="password" name="u_password_c" id="u_password_c"
placeholder="Password">
<i class="la la-lock"></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="password" name="repeat-password_c"
id="repeat-password_c"
placeholder="Repeat Password"
onfocusout="return checkPass('C')">
<i class="la la-lock"></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="checky-sec st2">
<div class="fgt-sec">
<input type="checkbox" name="u_terms_c" id="u_terms_c">
<label for="u_terms_c"><span></span></label>
<span></span>
</label>
<small>Yes, I understand and agree to the workwise Terms &
Conditions.</small>
</div><!--fgt-sec end-->
</div>
</div>
<div class="col-lg-12 no-pdd">
<button type="submit" name="company" value="submit"
onclick="return checkUserRegForm('C')">Get Started
</button>
</div>
</div>
</form>
at this point when i run my code and enter data into form, when i Submit i get a form error because forms don't see value into my fields:
ERROR-> {'u_fullname': [ValidationError(['This field is required.'])], 'u_email': [ValidationError(['This field is required.'])], 'all': [ValidationError(['Please read and accept our Terms of Service'])]}
How can i link my form fields name to my html element name value?
So many thanks in advance
Here's a link to docs on the subject rendering fields manually.
I looked for awhile and this is what I came up with. I apologize I left some stuff out. In your view if you are able to get 'country code' options and 'job' options you could look over them in them template.
I added value="{{ form.u_fullname }}", and value="{{ form.u_terms }}".
<form method="" action="">
{% csrf_token %}
{{ form.errors }}
<div class="row">
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type='text' name="u_fullname_C" id="u_fullname_c"
value="{{ form.u_fullname }}" placeholder="">
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<select name="u_country_c" id="">
{% for option in options %}
<option value="{{ option.pk }}">{{ option.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<select name="u_job_c" id="u_job_c" value="{{ form.u_job }}">
{% for job in jobs %}
<option value="{{ job.pk }}">{{ job.name }}</option>
{% endfor %}
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type='text' name='u_email_c' id='u_email_c' placeholder="" value="{{ form.u_email }}">
<i class="la la-envelope"></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="password" name="u_password_c" id="u_password_c" placeholder="Password">
<i class=""></i>
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="sn-field">
<input type="password" name="repeat-password_c" id="repeat-password_c" placeholder="" onfocusout="return checkPass('C')">
</div>
</div>
<div class="col-lg-12 no-pdd">
<div class="checky-sec st2">
<div class="fgt-sec">
<input type="checkbox" value="{{ form.u_terms }}" name="u_terms_c" id="u_terms_c">
<label for="u_terms_c"><span></span>
<span></span>
</label>
<small>Yes, I understand and agree to the workwise Terms &
Conditions.
</small>
</div>
</div>
</div>
<div class="col-lg-12 no-pdd">
<button type='submit' name='company' value='submit' onclick="return checkUserRegForm('C')">
Get Started
</button>
</div>
</div>
</form>
If you are using a class view
class ProfileView(CreateView):
form_class = UserProfileForm
success_url = '/'
def form_valid(self, form):
user_profile = form.save(commit=False)
user_profile.updated = datetime.datetime.now()
user_profile.save()
return super().form_valid(form)
Or a function view:
def user_profile_view(request):
if request.method == 'POST':
form = ProfileModelForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
fullname = cd['u_fullname']
UserProfile.objects.create(user=request.user, u_fullname=fullname)
return redirect('')
else:
form = ProfileModelForm()
Would you be able to provide your views.py file? I'm still semi new to Django so let me know if you are still having troubles.

How do I differentiate between Django messages in templates while using nested modals?

So, I've been racking my brain on this for 2 days now. Any help would be awesome!
At the heart of my issue, I believe, is that I have nested modals and a custom bootstrap form in both: the first for login, and the second for signup. Let's assume in one case I want to do all my validations server-side, and possibly get full control over each of the error validation messages, as well as how and where they should appear respective to their input. How do I do that using django.contrib.messages?
** If I could use some of Bootstrap 4's built-in methods for validation as a first line of defense, or data-validate-on-blur to work like how it does with Zurb Foundation's Abide, even better.
Template tags in each base.html modal:
{% if messages %}
<div class='container-fluid bg-white mt-5 pt-5 pl-4 mb-4'>
{% for message in messages %}
<p class="small font-poller text-danger">{{ message }}</p>
{% endfor %}
</div>
{% endif %}
Trials and tribulations thus far:
As it stands, and with the various work-arounds I've found on Stack Overflow, i.e. using jQuery to toggle the modal (not the prettiest as it reloads the page), the best I've been able to do still bleeds my messages in between modals and/or my redirect views.
I've read threads on how to clear Django messages, and thought that might be a fix, so if after I close a modal or open a new modal, the messages essentially are cleared out until the form is submitted once again. In other words, the login error messages are unique to the login modal when its form's submit button is pressed, and signup error messages are unique to the signup modal when its form's submit button is pressed.
Unfortunately, I haven't figured out how to use a view (views.py), to successfully achieve this. The thought comes to mind that since because I'm using modals to trigger that event, I would have to use jQuery for that, but I have failed on that front also. I'm really hoping there is a more straight-forward solution to this.
Thanks in advance,
Dev
PS - my snippets:
views.py
def signup(request):
signup_errors = User.objects.validation(request.POST, 'register')
if len(signup_errors):
for error in signup_errors.values():
messages.error(request, error)
return redirect('/')
else:
new_user = User.objects.create(
first_name = request.POST['first_name'],
last_name = request.POST['last_name'],
dob = request.POST['dob'],
phone = request.POST['phone'],
address = request.POST['address'],
city = request.POST['city'],
state = request.POST['state'],
zipcode = request.POST['zipcode'],
email = request.POST['email'],
password =
bcrypt.hashpw(request.POST['password'].encode(), bcrypt.gensalt()))
request.session['first_name'] = new_user.first_name
request.session['id'] = new_user.id
messages.info(request, 'You have successfully submitted your
information.')
return redirect('/menu')
def login(request):
login_errors = User.objects.validation(request.POST, 'login')
if len(login_errors):
for error in login_errors.values():
messages.error(request, error)
return redirect('/')
else:
current_user = User.objects.get(email=request.POST['email'])
request.session['first_name'] = current_user.first_name
request.session['id'] = current_user.id
messages.info(request, 'You have successfully logged in.')
return redirect('/menu')
models.py
class UserManager(models.Manager):
def validation(self, postData, error_validation):
errors = {}
if error_validation == 'register':
if not NAME_REGEX.match(postData['first_name']):
errors['first_name'] = "First name can only contain
letters!"
if len(postData['last_name']) < 1:
errors['last_name'] = "Last name cannot be blank."
if not NAME_REGEX.match(postData['last_name']):
errors['last_name'] = "Last name can only contain letters!"
if error_validation == 'login':
user = User.objects.filter(email=postData['email'])
if not user:
errors['user_login'] = "No account with that email in
our system."
elif not bcrypt.checkpw(postData['password'].encode(),
user[0].password.encode()):
errors['password_login'] = "Invalid email and/or
password!"
return errors
login modal in base.html
<div class="modal fade text-dark" id="loginModal">
<div class="modal-dialog">
<div class="modal-content font-paytone">
<div class="modal-header shadow p-3 bg_primary rounded">
<h5 class="modal-title font-poller text-light text_shadow_success2" id="loginModal">Login <i class="fa fa-user text-center ml-1"></i></h5>
<button class="close" data-dismiss="modal"><span>×</span></button>
</div>
<div class="modal-body">
<form id="login-form" action="{% url 'ecommerce_app:login' %}" method="POST" novalidate>
{% csrf_token %}
<div class="form-group">
<input type="email" name="email" class="form-control form-control-lg" placeholder="Email" required>
</div>
<div class="form-group">
<input type="password" name="password" class="form-control form-control-lg" placeholder="Password" required>
</div>
<input id="login-form-submit-btn" type="submit" class="btn btn-success btn-block border bg_primary btn_login" value="Log In">
</form>
<p class="pt-2 font-passion">Don't have an account? Sign up below!</p>
<button id="login-form-signup-btn" class="btn btn-info btn-block border" data-toggle="modal" data-target="#registerModal">Sign Up</button>
</div>
{% if messages %}
<div class="modal-footer">
<div class='container-fluid bg-white'>
{% for message in messages %}
<p class="small font-poller text-danger">{{ message }}</p>
{% endfor %}
</div>
</div>
{% endif %}
</div>
</div>
</div>
register modal in base.html
<div class="modal fade text-dark" id="registerModal">
<div class="modal-dialog">
<div class="modal-content font-paytone">
<div class="modal-header shadow p-3 bg_primary rounded">
<h5 class="modal-title font-poller text-light text_shadow_info" id="registerModal">Sign Me Up! <i class="fa fa-user-plus ml-1"></i></h5>
<button class="close" data-dismiss="modal"><span>×</span></button>
</div>
<div class="modal-body">
<form id='signup-form' action="/signup/" method="POST" novalidate>
{% csrf_token %}
<div class="form-row">
<div class="form-group col-md-6">
<label for="first_name">First Name</label>
<input type="text" name="first_name" class="form-control" required>
</div>
<div class="form-group col-md-6">
<label for="last_name">Last Name</label>
<input type="text" name="last_name" class="form-control" required>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<label for="dob">Date of Birth</label>
<input type="date" name="dob" class="form-control" required>
</div>
<div class="form-group col-md-6">
<label for="phone">Phone #</label>
<input type="tel" name="phone" class="form-control" required>
</div>
</div>
<div class="form-group">
<label for="address">Address</label>
<input type="text" name="address" class="form-control" placeholder="Street" required>
</div>
<div class="form-group">
<div class="form-row">
<div class="col-7">
<input type="text" class="form-control" name="city" placeholder="City" required>
</div>
<div class="col">
<input type="text" class="form-control" name="state" placeholder="State" required>
</div>
<div class="col">
<input type="text" pattern="[0-9]{5}" name="zipcode" class="form-control" placeholder="Zip" required>
</div>
</div>
</div>
<div class="form-group">
<label for="email">Email</label>
<input type="email" name="email" class="form-control" required>
</div>
<div class="form-row">
<div class="form-group col-md-6">
<!-- <label for="password">Password</label> -->
<input type="password" name="password" class="form-control" placeholder="Password" required>
</div>
<div class="form-group col-md-6">
<!-- <label for="confirm">Confirm Password</label> -->
<input type="password" name="confirm" class="form-control" placeholder="Confirm Password" required>
</div>
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-info btn-block font-fredoka">Register</button>
{% if messages %}
<div class='container-fluid bg-white mt-5 pt-5 pl-4 mb-4'>
{% for message in messages %}
<p class="small font-poller text-danger">{{ message }}</p>
{% endfor %}
</div>
{% endif %}
</div>
</form>
</div>
</div>
</div>
PSS - if I can help to clarify anything else please let me know
Well, I think I solved my own problem and am somehow compelled to share with others the solution as I think I actually lost sleep over this one. Anyway, I'm not really sure if this is what Django message class 'extra_tags' attribute was originally intended for, but for all intents and purposes it is a clean fix and allows me control over both server-side and client validation messages.
First, I assign extra_tags to 'register' and 'login' respectively when I create and append each message instance:
views.py
def signup(request):
errors = User.objects.validation(request.POST, 'register')
if len(errors):
for error in errors.values():
messages.add_message(request, messages.ERROR, error, extra_tags="register")
return redirect('/')
def login(request):
errors = User.objects.validation(request.POST, 'login')
if len(errors):
for error in errors.values():
messages.add_message(request, messages.ERROR, error, extra_tags="login")
return redirect('/')
I check to see if there are messages, then iterate through them, checking if the tag is 'register' (or 'login'), and if so, render some text, if not, don't render anything.
base.html
{% if messages %}
{% for message in messages %}
{% if 'register' in message.tags %}
<p class="small font-poller text-danger registration_error_message">{{ message }}</p>
{% endif %}
{% endfor %}
{% endif %}
Last but not least, after you submit the form through either modal, you will need to reload the modal with the aforementioned error (or success) messages. To have each modal show its respective messages you will have to differentiate and then toggle to open each one the same way I did using template_tags in the base.html, only this time using a little jQuery:
<script>
$(document).ready(function() {
{% if messages %}
{% for message in messages %}
{% if 'login' in message.tags %}
$('#loginModal').modal('toggle');
{% elif 'register' in message.tags %}
$('#registerModal').modal('toggle');
{% endif %}
{% endfor %}
{% endif %}
});
</script>