Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update only specific fields in django model?

Tags:

django

I want to update only specific fields in my model. This is my models.py

class Teacher(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    image = models.ImageField(upload_to='teacher/images')
    phone = models.CharField(max_length=15)
    address = models.CharField(max_length=25)
    salary = models.DecimalField(max_digits=20, decimal_places=2)
    joindate = models.DateField(auto_now_add=True)
    status = models.BooleanField(default=True)

And this is my forms.py

class TeacherForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'username', 'email', 'password']


class TeacherExtraForm(forms.ModelForm):
    class Meta:
        model = models.Teacher
        fields = ['phone', 'address', 'salary', 'status', 'image']

And this is my views.py

def update_teacher(request, pk):
    teacher = models.Teacher.objects.get(id=pk)
    user = models.User.objects.get(id=teacher.user_id)
    form1 = forms.TeacherForm(instance=user)
    form2 = forms.TeacherExtraForm(instance=teacher)
    context = {
        'teacher': teacher,
        'user': user,
        'form1': form1,
        'form2': form2
    }
    if request.method == 'POST':
        form1 = forms.TeacherForm(request.POST, instance=user)
        form2 = forms.TeacherExtraForm(request.POST, instance=teacher)
        if form1.is_valid() and form2.is_valid():
            user = form1.save(commit=False)
       
            user.save(update_fields=['first_name', 'last_name', 'email', 'username'])
            f2 = form2.save(commit=False)
            f2.status = True
            f2.save(update_fields=['phone', 'address', 'salary', 'status'])
            return redirect('Teacher:teacher_index')
    return render(request, 'Teacher/update_teacher.html', context)

Here I only want to update the first_name, last_name, email, username, phone, address, salary and status without affecting the password and image field. When I add the password and image field also, it works but I do not want to update password and image here.

like image 530
sd077 Avatar asked Sep 11 '25 00:09

sd077


1 Answers

Typically in such situations, one makes two forms, one to create and one to update. Django itself for example has a UserCreateForm [Django-doc] and a UserChangeForm [Django-doc]. We thus can construct two additional forms:

class TeacherUpdateForm(forms.ModelForm):
    class Meta:
        model = User
        fields = ['first_name', 'last_name', 'username', 'email']

class TeacherUpdateExtraForm(forms.ModelForm):
    class Meta:
        model = models.Teacher
        fields = ['phone', 'address', 'salary', 'status']

In the view, we thus then work with these forms:

from django.shortcuts import get_object_or_404

def update_teacher(request, pk):
    teacher = get_object_or_404(models.Teacher, pk=pk)
    user = teacher.user
    if request.method == 'POST':
        form1 = forms.TeacherUpdateForm(request.POST, instance=user)
        form2 = forms.TeacherUpdateExtraForm(request.POST, instance=teacher)
        if form1.is_valid() and form2.is_valid():
            form1.save()
            from2.instance.status = True
            form2.save()
            return redirect('Teacher:teacher_index')
    else:
        form1 = forms.TeacherUpdateForm(instance=user)
        form2 = forms.TeacherUpdateExtraForm(instance=teacher)
    context = {
        'teacher': teacher,
        'user': user,
        'form1': form1,
        'form2': form2
    }
    return render(request, 'Teacher/update_teacher.html', context)
like image 195
Willem Van Onsem Avatar answered Sep 13 '25 14:09

Willem Van Onsem