Django RelatedObjectDoesNotExist в методе очистки модели, но только при тестировании - PullRequest
0 голосов
/ 22 апреля 2019

У меня очень странное поведение, когда эта функция прекрасно работает в приложении, но вызывает ее при вызове в тестовой среде.

У меня есть этот класс модели с этим чистым методом:

def clean(self):
    self._check_subcategory_consistency()
    # other checks
    # ...

def _check_subcategory_consistency(self):
    # checks if the subcategory belongs to the category specified
    if self.subcategory.category != self.category:
        raise ValidationError({'subcategory' : 'this field does not belong to the correct category'})

Это прекрасно работает в приложении как при создании нового экземпляра модели, так и при его обновлении.

Но затем, когда я тестирую представление с отправкой POST, возникает следующая ошибка:

poi.models.PointOfInterests.subcategory.RelatedObjectDoesNotExist: PointOfInterests has no subcategory.

Вот тест:

class ViewTest(TestCase):

    @classmethod
    def setUpTestData(cls):
        # fill the DB with all the utility tables (category and subcategory)
        populate.populate()
        cls.factory = RequestFactory()
        cls.user = User.objects.create_user(username='user', password='secret')
        cls.point = populate.add_default_point()
        cls.point.save() 

    # some other tests in the middle...

    def test_new_post(self):
        request = self.factory.post(reverse('new'))
        post_dict = model_to_dict(self.point)
        # avoid name clash with the already created point
        post_dict['name'] = 'new name'
        request.POST = post_dict
        # add mandatory thumbnail
        with open('static/images/placeholder.jpg', 'rb') as uploaded_image:
            request.FILES['thumbnail'] = uploaded_image
            request.FILES['thumbnail'].read()
        request.user = self.user
        response = views.new(request)
        self.assertEqual(response.status_code, 302)
        self.assertEqual(PointOfInterests.objects.all().count(), 2)
        PointOfInterests.objects.get(name='new name').delete()

А также, вот вид:

@login_required
def new(request):

    if request.method == 'POST':
        form = PoiForm(request.POST, files=request.FILES)

        if form.is_valid():
            point = form.save(commit=False)
            point.owner = request.user
            point.save()
            return HttpResponseRedirect(reverse('show', kwargs={'slug': point.slug}))

    else:
        form = PoiForm()

    context_dict = {}
    context_dict['form'] = form
    return render(request, 'poi/new.html', {'form' : form})

Форма - это обычная форма без переопределенного метода.

Итак, в заключение, очень странно, что несоответствие ошибки появляется только при тестировании.

Кто-нибудь имеет представление о том, почему это происходит? Может быть, тест ведет себя не так, как приложение?

Любая помощь будет принята с благодарностью.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...