0

I have created this Django model:

class Teacher(models.Model):
    user = models.OneToOneField('auth.User', on_delete=models.CASCADE, default=1)
    surname = models.CharField(max_length=15, null=True)
    creation_date = models.DateTimeField('creation date', auto_now_add=True)
    deletion_date = models.DateTimeField('deletion date', null=True, blank=True)

and a form to represent it in read-only mode:

class TeacherViewForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super(TeacherViewForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            for field in self.fields:
                self.fields[field].widget.attrs['disabled'] = True

    class Meta:
        model = Teacher
        exclude = ['deletion_date']

The view looks like this:

class TeacherViewDetail(generic.DetailView):
    model = Teacher
    template_name = 'control/teacher_detail.html'
    form_class = TeacherViewForm

    def get_form(self):
        # Instantiate the form
        form = self.form_class(instance=self.object)

        return form

    def get_context_data(self, **kwargs):
        context = super(TeacherViewDetail, self).get_context_data(**kwargs)
        context.update({
            'form': self.get_form(),
        })

        return context

As you can see, there is a OneToOne relation between the Teacher and the auth.User models. I need to displayfirst_name and last_name from auth.User model, but only the username is shown.

How can I display these fields the same way field Teacher.surname is being displayed? Do I have to include them in the model, the form.fields or is there a property I have to modify in order to achieve it?

Thanks

juankysmith
  • 11,839
  • 5
  • 37
  • 62

1 Answers1

0

You would have to remove the user field and add the appropriate fields instead. Then in your form's __init__, fill the initial values:

# forms.py
class TeacherViewForm(ModelForm):
    first_name = forms.CharField()
    last_name = forms.CharField()

    def __init__(self, *args, **kwargs):
        super(TeacherViewForm, self).__init__(*args, **kwargs)
        instance = getattr(self, 'instance', None)
        if instance and instance.pk:
            for field in self.fields:
                self.fields[field].widget.attrs['disabled'] = True
            # set initial values
            self.fields['first_name'].initial = instance.user.first_name
            self.fields['last_name'].initial = instance.user.last_name

    class Meta:
        model = Teacher
        exclude = ['user', 'deletion_date']  # exclude user

But why do you use a form at all if you disable all fields? You can just render all this information much more freely in the template.

user2390182
  • 72,016
  • 6
  • 67
  • 89
  • Thanks. I don't need a string suitable for representing the User, but to display auth.User fields (first_name and last_name) the same way Teacher fields are displayed – juankysmith Jan 14 '17 at 12:38
  • Teacher fields are 'surname' and 'creation_date' ('deletion_date' is excluded). In the template, I want to be able to see these Teacher fields with 'first_name' and 'last_name' from auth.User model – juankysmith Jan 14 '17 at 12:47
  • I see, changed my answer – user2390182 Jan 14 '17 at 13:30