Question

Been trying to determine the "most" elegant solution to dropping a field from a from if the user is not is_staff/is_superuser. Found one that works, with a minimal amount of code. Originally I though to add 'close' to the 'exclude' meta or use two different forms. But this seems to document what's going on. The logic is in the 'views.py' which is where I feel it blongs.

My question: Is this safe? I've not seen forms manipulated in this fashion, it works.

models.py

class Update(models.Model):
    denial = models.ForeignKey(Denial)
    user = models.ForeignKey(User)
    action = models.CharField(max_length=1, choices=ACTION_CHOICES)
    notes = models.TextField(blank=True, null=True)
    timestamp = models.DateTimeField(default=datetime.datetime.utcnow().replace(tzinfo=utc))
    close = models.BooleanField(default=False)

forms.py

class UpdateForm(ModelForm):
    class Meta:
        model = Update
        exclude = ['user', 'timestamp', 'denial', ]

views.py

class UpdateView(CreateView):
    model = Update
    form_class = UpdateForm
    success_url = '/denials/'
    template_name = 'denials/update_detail.html'

    def get_form(self, form_class):
        form = super(UpdateView, self).get_form(form_class)
        if not self.request.user.is_staff:
            form.fields.pop('close') # ordinary users cannot close tickets.
        return form
Était-ce utile?

La solution

Yes, your approach is perfectly valid. The FormMixin was designed so you can override methods related to managing the form in the view and it is straightforward to test.

However, should yours or someone else's dynamic modifications of the resulting form object become too extensive, it would probably be best to define several form classes and use get_form_class() to pick the correct form class to instantiate the form object from.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top