Reputation: 483
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
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
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