Home > Blockchain >  django test a modelform - ValidationError not a valid UUID
django test a modelform - ValidationError not a valid UUID

Time:03-20

I am testing a modelform and getting a ValidationError. My model, view and test are as follows:

model

class Course(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL,
                             on_delete=models.CASCADE)
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    course_name = models.CharField(max_length=30)
    grade_level = models.CharField(max_length=4, default="SEC")

view

@ method_decorator([login_required, teacher_required], name='dispatch')
class CourseUpdateView(PermissionRequiredMixin, UpdateView):
    raise_exceptions = True
    permission_required = 'gradebook.change_course'
    permission_denied_message = "You don't have access to this."

    model = Course
    fields = ['course_name', 'grade_level', ]
    template_name_suffix = '_update'

    def get_success_url(self, *args, **kwargs):
        return reverse('gradebook:coursedetail', kwargs={'course_pk': self.object.pk})

form

class CourseForm(ModelForm):
    class Meta:
        model = Course
        fields = ('course_name', 'grade_level',)

    def __init__(self, user, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.qc = Course.objects.filter(user=user)

    def clean(self):
        super(CourseForm, self).clean()
        course_name = self.cleaned_data.get('course_name')
        if course_name and self.qc.filter(course_name__iexact=course_name).exists():
            raise ValidationError("A course with that name already exists.")
        if len(course_name) > 20:
            if len(course_name) > 10:
                raise ValidationError(
                    "Your course name cannot be longer than 20 characters")

        return self.cleaned_data

Test

class CourseUpdateTests(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.user = CustomUser.objects.create_user(
            username='tester',
            email='[email protected]',
            password='tester123',
            is_teacher=True,
            is_active=True,
        )
        cls.user.save()

    def test_CourseUpdate_valid(self):
        request = HttpRequest()
        request.POST = {
            'user': self.user,
            'id': '4d192045-07fa-477f-bac2-5a99fe2e7d46',
            'course_name': "Science",
            'grade_level': "SEC"
        }
        form = CourseForm(request.POST)
        self.assertTrue(form.is_valid())

The error I get:

Raise exceptions.ValidationError(
django.core.exceptions.ValidationError: ["“{'user': <CustomUser: tester>, 'id': '4d192045-07fa-477f-bac2-5a99fe2e7d46', 'course_name': 'Science', 'grade_level': 'SEC'}” is not a valid UUID."]

I have tried not putting the id in the request.POST but get the same error.

I originally tried to test for a valid form by using:

def test_CourseUpdate_valid(self):
        form = CourseForm(data={
            'user': self.user,
            'id': '4d192045-07fa-477f-bac2-5a99fe2e7c04',
            'course_name': "Science",
            'grade_level': "SEC"
        },)
        self.assertTrue(form.is_valid())

This did not work though, giving me the error TypeError: __init__() missing 1 required positional argument: 'user'

CodePudding user response:

Your original solution was not good because you were missing the user positional argument in the form init function.

Secondly, your CourseForm class should specify the rest of the fields (id, and user) if you want to pass them to the form.

You could probably just not pass id and user to the CourseForm data in the test as they aren't relevant.

This should work:

def test_CourseUpdate_valid(self):
        form = CourseForm(self.user, data={
            'course_name': "Science",
            'grade_level': "SEC"
        },)
        self.assertTrue(form.is_valid())

Can you try that and let me know if the problem persists?

  • Related