Form partial

Hi
I have a question regarding how one should handle “partial” forms.

Example model:

Class Process(models.Model):
    title = models.CharField(...)
    description = models.TextField(...)
    date = models.DateField(...)

What i want to be able to do, is to create multiple ways of editing this model.
As example, i want to only show a form with the description field to some users, but all three fields to other users.

I tend to believe that creating multiple very similar modelforms cant be optimal, example:

class ProcessForm(forms.ModelForm):
    class Meta:
        model = Process
        fields = ["title", "description", "date"]

class ProcessDescriptionForm(forms.ModelForm):
    class Meta:
        model = Process
        fields = ["description"]

Therefore ive been experimenting with overwriting init and adding a “active_fields” kwarg:

#views.py
form = ProcessForm(request.POST or None, instance=process, active_fields=request.GET.get('active_fields'))

#forms.py
class ProcessForm(forms.ModelForm):
    class Meta:
        model = Process
        fields = fields = ["title", "description", "date"]

    def __init__(self, *args, **kwargs):   
        active_fields = kwargs.pop("active_fields", None)
        super(ProcessForm, self).__init__(*args, **kwargs)
        if active_fields:
            for field_name in self.fields.copy():
                if not field_name in active_fields:
                     self.fields.pop(field_name, None)

How would you handle such “partial” forms?

Bw. Martin

We have many cases when we remove some fields from a form based on a flag typically passed from the view:

class ProcessForm(forms.ModelForm):
    class Meta:
        model = Process
        fields = ["title", "description", "date"]

    def __init__(self, can_edit_description: bool, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if not can_edit_description:
            del self.fields["description"]

And the view:

class ProcessUpdateView(UpdateView):
    form_class = ProcessForm

   def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs["can_edit_description"] = self.request.user.has_perm("foo.change_description")
        return kwargs

Thank you for your reply @washeck, and for the snippets which are very helpful!