Reputation: 174
I am using the following ModelForm:
class ListingQuoteForm(forms.ModelForm):
author_phone = forms.CharField(validators=[validate_phone_number])
content = forms.CharField(
label='Your message',
min_length=50,
widget=forms.Textarea(attrs={'rows': 4}),
help_text='Please provide a few details about your race and your requirements',
)
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user.is_authenticated:
self.fields['author_name'].initial = user.full_name(strict=True)
self.fields['author_email'].initial = user.email
self.fields['author_email'].disabled = True
class Meta:
model = QuoteRequest
fields = ('author_name', 'author_email', 'author_phone', 'content')
labels = {
'author_name': 'Your name',
'author_email': 'Your email',
'author_phone': 'Your phone number',
}
and rendering it in the following template:
{% load crispy_forms_tags %}
<div class="listing-section" id="quote-form">
<div class="listing-section-header">
{% if primary_category.quote_request_type == 'quote' %}
<h2>Request a quote</h2>
{% elif primary_category.quote_request_type == 'info' %}
<h2>Request more info</h2>
{% endif %}
</div>
<div class="listing-section-body">
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ quote_form.author_name|as_crispy_field }}
{{ quote_form.author_email|as_crispy_field }}
{{ quote_form.author_phone|as_crispy_field }}
{{ quote_form.content|as_crispy_field }}
<div class="form-group">
<button class="standard-button standard-button--submit" type="submit">Send</button>
</div>
</form>
</div>
</div>
When the content
field min length validation fails, a message is displayed like so:
But when my custom phone number validation fails, the error displays under the field like so:
EDIT: Here's the QuoteRequest
object as well:
class QuoteRequest(models.Model, ModelMixin):
SOURCES = (
('listing_page', 'Listing page'),
('dashboard_offers', 'Dashboard offers'),
('concierge', 'Concierge'),
)
source = models.CharField(max_length=18, null=True, blank=True, choices=SOURCES)
author = models.ForeignKey(User, null=True, blank=True, on_delete=models.SET_NULL, related_name='quote_requests')
author_name = models.CharField(max_length=40)
author_email = models.EmailField()
author_phone = models.CharField(max_length=24, null=True, blank=True, validators=[validate_phone_number])
content = models.TextField()
category = models.ForeignKey(Category, null=True, blank=True, on_delete=models.CASCADE, related_name='quote_requests')
listing = models.ForeignKey(Listing, null=True, blank=True, on_delete=models.CASCADE, related_name='quote_requests')
offer = models.ForeignKey(Offer, null=True, blank=True, on_delete=models.SET_NULL, related_name='quote_requests')
race = models.ForeignKey(Race, null=True, blank=True, on_delete=models.SET_NULL, related_name='quote_requests')
approved = models.BooleanField(default=False)
date_created = models.DateTimeField(auto_now_add=True)
date_approved = models.DateTimeField(null=True)
How can I get my phone number validation error to display the same way the in-built min length validation does for the CharField?
Upvotes: 0
Views: 1139
Reputation: 8837
You can use novalidate
on form, to off default behavior of html5 of showing errors so that Django's errors can be shown.
So:
<form method="POST" enctype="multipart/form-data" novalidate>
{% csrf_token %}
{{ quote_form.author_name|as_crispy_field }}
{{ quote_form.author_email|as_crispy_field }}
{{ quote_form.author_phone|as_crispy_field }}
{{ quote_form.content|as_crispy_field }}
<div class="form-group">
<button class="standard-button standard-button--submit" type="submit">Send</button>
</div>
</form>
Upvotes: 1