Home > Software design >  Pass data from model clean function to template
Pass data from model clean function to template

Time:01-17

Is there a way to pass a dictionary of errors from def clean function to the template ? I think that context_processors can do the trick but not sure if its the correct way.

CodePudding user response:

its a Using context processors is one method for doing this. A Python function called a context processor has two arguments: the request object and a dictionary holding the context information. The template will have additional variables that can later be added to the context. Here is an example how to transmit a dictionary of errors from a form's clean function to the template using a context processor: forms.py

class MyForm(forms.Form):

    def clean(self):
        cleaned_data = super().clean()
        errors = {}
        # perform validation and add errors to the errors dictionary
        if errors:
            self.add_error(None, errors)

context_processor.py

def form_errors(request):
    if hasattr(request, 'form_errors'):
        return {'form_errors': request.form_errors}
    return {}

Add the following in settings.py

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'context_processors': [
                ...
                'myapp.context_processors.form_errors',
            ],
        },
    },
]

views.py

def my_view(request):
    form = MyForm(request.POST or None)
    if form.is_valid():
        # do something with the form data
        pass
    else:
        request.form_errors = form.errors
    return render(request, 'index.html', {'form': form})

index.html

{% for field, errors in form_errors.items %}
    {% for error in errors %}
        <p>{{ error }}</p>
    {% endfor %}
{% endfor %}

Using this method, the form errors variable may be used to retrieve the errors dictionary in the template. There are another alternative you can use; django messages framework

CodePudding user response:

This is how you implement it through model. models.py

class MyModel(models.Model):
    def clean(self):
        errors = {}
        # perform validation and add errors to the errors dictionary
        if errors:
            raise ValidationError(errors)

views.py

def my_view(request):
    my_model_instance = MyModel.objects.get(pk=1)
    try:
        my_model_instance.clean()
    except ValidationError as e:
        request.model_errors = e.message_dict
    return render(request, 'index.html', {'my_model_instance': my_model_instance})

context_processor.py

def model_errors(request):
    if hasattr(request, 'model_errors'):
        return {'model_errors': request.model_errors}
    return {}

settings.py

TEMPLATES = [
    {
        ...
        'OPTIONS': {
            'context_processors': [
                ...
                'myapp.context_processors.model_errors',
            ],
        },
    },
]

index.html

<!-- index.html -->
{% for field, errors in model_errors.items %}
    {% for error in errors %}
        <p>{{ error }}</p>
    {% endfor %}
{% endfor %}
  • Related