Reputation: 580
I have class based modelview where I want the model/instance to be created or updated. If updating, I want the fields to show their current values. I have this working except that the instance is being created just by loading the view/template. As soon as the page loads, the object is saved. I think it's very important that the save is not done until the submit button is clicked.
I also want to override the model's save() method because I need to check what field is being updated and update a different model/object.
Model
class GradeBookSetup(DirtyFieldsMixin, models.Model):
user = models.OneToOneField(CustomUser, on_delete=CASCADE)
level1 = models.IntegerField(default=55)
scale_mode = models.CharField(max_length=7, blank=True, default="VSB")
teacher_show_sec_percent = models.BooleanField(default=True)
def save(self, *args, **kwargs):
super(GradeBookSetup, self).save(*args, **kwargs)
if 'scale_mode' in dirty_fields:
objs = Grade.objects.filter(user=self.user)
n = 0
for grade in objs:
objs[n].score = "BEG"
View
@method_decorator([login_required], name='dispatch')
class GradeBookSetupCreateView(UpdateView):
form_class = GradeBookSetupForm
model = GradeBookSetup
success_url = "/gradebook/"
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
def get_object(self, queryset=None):
obj, created = GradeBookSetup.objects.get_or_create(
user=self.request.user)
return obj
Form
class GradeBookSetupForm(forms.ModelForm):
class Meta:
model = GradeBookSetup
fields = ['level1', 'scale_mode', 'teacher_show_sec_percent']
labels = {
"level1": "What percent?",
"scale_mode": "Choose your proficiency scale.",
'teacher_show_sec_percent': "Teacher view (10-12), show percent",
}
EDIT
My next try is to move the get_or_create
into the form_valid
method as suggested by hendrikschneider. I still need to get the object to display the correct values after the initial save so I mean to do this with the try:
. I had to change the get_or_create
to update_or_create
.
def form_valid(self, form):
form.instance.user = self.request.user
form.instance, created = GradeBookSetup.objects.update_or_create(
user=self.request.user, defaults={'scale_mode':form.instance.scale_mode})
return super().form_valid(form)
def get_object(self, queryset=None):
try:
obj = GradeBookSetup.objects.get(user=self.request.user)
return obj
except:
pass
Upvotes: 0
Views: 34
Reputation: 1846
The issue is your get_object method. The method is called when a get and when a post request is executed. As you use get_or_create there, it is always executed. Make sure that you only get_or_create in your form_valid method and not in get_object.
Upvotes: 2