Panos
Panos

Reputation: 174

Display of Django ModelForm field validation errors in crispy forms

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:

enter image description here

But when my custom phone number validation fails, the error displays under the field like so:

enter image description here

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

Answers (1)

Sunderam Dubey
Sunderam Dubey

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

Related Questions