sd077
sd077

Reputation: 483

How to update only specific fields in django model?

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.

Upvotes: 4

Views: 2802

Answers (2)

Manish Sharma
Manish Sharma

Reputation: 1

Note: I have used d-none class for other field which i don't want to update

  ====Font End =====     
            <div class="row g-2 mb-3">
              <div class="col-md d-none">
                  {{ form.name|as_crispy_field }}
              </div>
          
                <div class="col-md">
                  {{ form.status|as_crispy_field}}
                </div>
            </div>
         
        ======Back End =======

class SingleObjUpdate(UpdateView):

model = ModelName
template_name = 'template.html'
form_class = FormName


        

Upvotes: 0

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476503

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)

Upvotes: 4

Related Questions