Issue
I have created a UniqueConstraint Meta Class for my model, and it works when I test it by intentionally creating a duplicate but I am getting an error page instead of being redirected back to the original page. Where do I insert the code to go back to the page that I was just on?
I assume the issue is in the view, but I have no idea what code to put in there and the Django docs contain nothing alluding to this problem.
Model:
class StudentScheduledClass(models.Model):
student = models.ForeignKey("users.User", on_delete=models.CASCADE, db_column="Student")
scheduled_class = models.ForeignKey("ScheduledClass", on_delete=models.CASCADE, db_column="ScheduledClass")
grade = models.FloatField(db_column="Grade", blank=True, null=True)
class Meta:
managed = True
db_table = "StudentScheduledClass"
verbose_name_plural = "StudentsScheduledClasses"
constraints = [
models.UniqueConstraint(fields=['student', 'scheduled_class'], name='student scheduled class restraint')
]
View:
class StudentScheduledClassCreateView(LoginRequiredMixin, CreateView):
model = StudentScheduledClass
context_object_name = "student_scheduled_class"
fields = ["student"]
def form_valid(self, form):
scheduled_class = self.kwargs["scheduled_class"]
form.instance.scheduled_class = ScheduledClass(scheduled_class)
return super().form_valid(form)
def get_success_url(self):
scheduled_class = self.kwargs["scheduled_class"]
return reverse("scheduled-class-detail", args={scheduled_class})
I'd like to just go back to the original page with an error message, instead I get this integrity error:
IntegrityError at /classes/student_scheduled_class_create/1/
UNIQUE constraint failed: StudentScheduledClass.Student, StudentScheduledClass.ScheduledClass
Request Method: POST
Request URL: http://localhost:8000/classes/student_scheduled_class_create/1/
Django Version: 2.2.2
Exception Type: IntegrityError
Exception Value:
UNIQUE constraint failed: StudentScheduledClass.Student, StudentScheduledClass.ScheduledClass
Solution
Your form only requires the field student
so it's valid because you haven't given its instance a value for scheduled_class
when it gets validated.
You should initialise your form with an instance
for which scheduled_class
is already set. You can do that in get_form_kwargs()
or, since that method passes self.object
as instance
, you can do that even simpler in the post()
:
def post(self, request, *args, **kwargs):
self.object = StudentScheduledClass(scheduled_class=kwargs['scheduled_class'])
return super().post(request, *args, **kwargs)
Alternatively, although a bit less clean (I like to think that once form_valid()
is called everything should be ok):
def form_valid(self, form):
scheduled_class = self.kwargs["scheduled_class"]
form.instance.scheduled_class = ScheduledClass(scheduled_class)
try:
return super().form_valid(form)
except IntegrityError:
return self.form_invalid(form)
The problem with the last one is that the form won't have any errors to show, so you'd probably want to add a Django message to the self.request
before returning (assuming you display any message in your template).
Answered By - dirkgroten
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.