Apostolos
Apostolos

Reputation: 8121

Choosing which fields appear in a modelform according to user

Lets say I have a model like the following:

class Patient(models.Model):
   #has some fields
   doctor = models.ForeignKey(User)

So a patient model has a doctor that treats him. I also have model form

class PatientForm(ModelForm):
    class Meta:
        model=Patient

So all fields are included. Lets say now frontdesk(nonstaff) can create patients and has to asign a doctor on them. So PatientForm works cause the doctor field will appear normally. But a doctor can create a patient too, but when a doctor(staff user) creates a patient the doctor field must be filled automatically by the connected user and not rendered in the template. Something like:

if request.user.is_staff():
    form = #PatientForm_without_doctor_field
else:
    form = PatientForm()

Can it be done using the same PatientForm class? Is it better to have to different ModelForms (one with field included and one with doctor excluded) and use it accordingly? which is the best approach for that? Is it better to have a new model form with request.user in the constructor?

Upvotes: 1

Views: 58

Answers (2)

arocks
arocks

Reputation: 2882

[Edit] While initializing you can set the initial values based on a keyword argument:

class PatientForm(ModelForm):

    def __init__(self, readonly_doctor=None, *args, **kwargs):
        super(StudentForm, self).__init__(*args, **kwargs)
        if readonly_doctor is not None:
            self.fields['doctor'].widget.attrs['readonly'] = True
            self.fields['doctor'].initial = readonly_doctor

    class Meta:
        model=Patient

Then you can conditionally pass it:

if request.user.is_staff():
    form = PatientForm(readonly_doctor=request.user)
else:
    form = PatientForm()

Upvotes: 0

ndpu
ndpu

Reputation: 22571

Pass request.user to form init in view:

def some_view(request):
     form = PatientForm(user=request.user)

and modify form fields according to user in form init after form creation:

from django.contrib.auth.models import AnonymousUser

class PatientForm(ModelForm):
    class Meta:
        model=Patient

    def __init__(self, *args, **kwargs):
        user = kwargs.pop('user', AnonymousUser())
        super(PatientForm, self).__init__(*args, **kwargs)
        if user.is_staff():
            # hide field and set doctor to request.user
            self.fields['doctor'].widget = forms.HiddenInput()
            self.fields['doctor'].initial = user

Upvotes: 1

Related Questions