pythondjangodjango-formsreadonlydjango-widget

instantiate a django form in readonly mode in a view function


I have a django 4 form having some widgets for the user to select some values:

from django import forms
from .app.model import MyModel
from bootstrap_datepicker_plus.widgets import DatePickerInput

class FooForm(forms.ModelForm):
   # stuff
    class Meta:
        model = FooModel
        fields = [
            "user_id",
            "created_at",
            "some_other_field",
        ]

        widgets = {
            "user_id": forms.NumberInput(),
            "created_at": DatePickerInput(),
            "some_other_field": forms.NumberInput(),
        }

I instantiate that form in several functions in the views.py file:

my_form_instance = forms.FooForm(
    data=data,
    user=request.user,
)

One function create_or_edit_foo() for creating a new or editing an existing record. And another function delete_foo() to delete a record. In the deletion function (used by a specific endpoint /foo/12/delete), I want to display the form but in read-only mode.

How could I achieve that?

I know I can add attrs={'readonly': True,} in each of the widget to make it non-editable. But this will also apply to the form instances used by the create_or_edit function in my views.

I'm using django 4.2 on Ubuntu 22.04 with Python 3.10.6.


Solution

  • For KISS, you Can use named argument.

    def delete_foo():
        my_form_instance = formes.fooForm(
            data = data,
            User = request.user,
            delete = True,
        )
    

    And in your form :

    class FooForm(forms.ModelForm):
        class Meta:
            model = FooModel
            fields = [
                "user_id",
                "created_at",
                "some_other_field",
            ]
    
            widgets = {             
                "user_id":forms.NumberInput(),
                "created_at": DatePickerInput(),
                "some_other_field": forms.NumberInput(),
            }
    
        def __init__(self, *args, delete=None, **kwargs):
            super(fooForm, self).__init__(*args, **kwargs)
            if delete:
                for field_name in self.fields : 
                    self.fields[field_name].widget.attrs['readonly'] = True