I'm building a Django project for a client that requires me to not user a simple form.save()
method to update a model field.
Basically, it looks like this:
I have this model with a CharField
who has unique=True
:
# models.py
class Course(models.Model):
name = models.CharField(max_length=20, unique=True)
other_field = models.CharField(max_length=10, null=True)
def __str__(self):
return self.name
That model has a form in forms.py
:
# forms.py
class CourseCreateForm(forms.ModelForm):
class Meta:
model = Course
fields = ['name', 'other_field']
I need to update this field through a function view (can't be class based in this scenario. Of course, literally it can, but for my student's project requirements it can't be) and I can't use the simple form.save()
function, so I need to do the full update code as if it was a normal form:
# views.py
def course_update(request, pk):
course = Course.objects.get(pk=pk)
course_queryset = Course.objects.filter(pk=pk)
if request.method == "POST":
form = CourseCreateForm(request.POST)
if form.is_valid():
name = form.cleaned_data['name']
other_field = form.cleaned_data['other_field']
course_queryset.update(name=name, other_field=other_field) # <-- Where I try to update
else:
print(form.errors)
return HttpResponseRedirect('../')
else:
form = CourseCreateForm(instance=course)
context = {
"form": form,
}
return render(request, 'base/course_update.html', context)
When I try to only update the other_field
, the change isn't made and in the formerrors I receive the error "Course with this Name already exists.", so I can't only change the other_field
data without also having to change the name
field because the name
field is unique.
How can you update a model instance's field that has unique=True without changing the unique value?
Hope this makes sense!
Thanks.
UPDATE:
Also wanted to add that it works perfectly fine when unique=True is turned off. I'm just curious how do you update a field normally when unique=True and you're adding in the same variable from a model form.
The reason that this will fail is because the ModelForm
thinks you are creating a new record, and thus it will check if an object with the given name already exists, and if so, it of course finds out the name already exists, hence the form is not valid.
You can pass the instance
to the form. In that case the form will exclude that item from the unique check:
def course_update(request, pk):
course = Course.objects.get(pk=pk)
course_queryset = Course.objects.filter(pk=pk)
if request.method == 'POST':
form = CourseCreateForm(request.POST, instance=course)
if form.is_valid():
name = name_form.cleaned_data['name']
other_field = course_form.cleaned_data['other_field']
course_queryset.update(name=name, other_field=other_field)
return HttpResponseRedirect('../')
else:
print(form.errors)
else:
form = CourseCreateForm(instance=course)
context = {
'name_form': name_form,
'course_form': course_form,
}
return render(request, 'base/course_update.html', context)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With