我可以在 Django 测试中以某种方式从 form_valid() 调用逻辑吗?
Can I somehow call logic from form_valid() in Django tests?
我正在尝试在我的简单论坛应用程序中测试 Post 模型创建的表单。我遇到的问题是,在我尝试在测试中保存表单后,出现错误 NOT NULL constraint failed: forum_web_post.user_id
,因为我在视图中的 form_valid()
方法中分配了用户。用户未通过表单传递,因为创建 post 的用户是发送请求的登录用户。
models.py
class Post(models.Model):
category = models.ForeignKey(Category, on_delete=models.PROTECT)
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
text = models.TextField()
created_at = models.DateTimeField(auto_now=True)
用户是从 django.contrib.auth.models
导入的,类别模型如下所示。
class Category(models.Model):
name = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now=True)
在 views.py
用户提交表单后,他将被重定向到他的个人资料页面
views.py
class PostCreate(generic.CreateView):
model = Post
form_class = PostForm
template_name = 'forum_web/post_edit.html'
def form_valid(self, form):
post = form.save(commit=False)
post.user = models.User.objects.get(id=self.request.user.id)
post.save()
return HttpResponseRedirect(reverse_lazy('forum:user_detail', kwargs={'pk': self.request.user.id}))
forms.py
class PostForm(ModelForm):
class Meta:
model = Post
fields = ['category', 'title', 'text']
tests.py
def test_post_form_create_should_pass(self):
# this dict is in setUp() as well as the test_category but for simplicity I will include it in this method
post_data = {
'category': self.test_category.pk,
'title': 'test_post',
'text': 'test_post_text'
}
post_count = Post.objects.count()
form = PostForm(data=self.post_data)
self.assertTrue(form.is_valid())
form.save()
self.assertEqual(post_count + 1, Post.objects.count())
如有任何帮助,我们将不胜感激!
您只是在测试表单。所以在你的测试中调用视图函数是没有意义的。在您的测试中保存表单之前,您应该使用 form.instance.user = ...
手动将用户分配给表单的实例,因为这是应该使用表单的方式。
此外,您应该通过实际登录用户并将请求发布到 PostCreate
视图来测试您的视图。您在此处测试视图是否正确保存了表单(并且您的 form_valid()
方法是否正常工作)。
注意:post.user = self.request.user
比使用 id
从数据库中重新获取用户要好。这是多余的。
我正在尝试在我的简单论坛应用程序中测试 Post 模型创建的表单。我遇到的问题是,在我尝试在测试中保存表单后,出现错误 NOT NULL constraint failed: forum_web_post.user_id
,因为我在视图中的 form_valid()
方法中分配了用户。用户未通过表单传递,因为创建 post 的用户是发送请求的登录用户。
models.py
class Post(models.Model):
category = models.ForeignKey(Category, on_delete=models.PROTECT)
user = models.ForeignKey(User, on_delete=models.CASCADE)
title = models.CharField(max_length=100)
text = models.TextField()
created_at = models.DateTimeField(auto_now=True)
用户是从 django.contrib.auth.models
导入的,类别模型如下所示。
class Category(models.Model):
name = models.CharField(max_length=100)
created_at = models.DateTimeField(auto_now=True)
在 views.py
用户提交表单后,他将被重定向到他的个人资料页面
views.py
class PostCreate(generic.CreateView):
model = Post
form_class = PostForm
template_name = 'forum_web/post_edit.html'
def form_valid(self, form):
post = form.save(commit=False)
post.user = models.User.objects.get(id=self.request.user.id)
post.save()
return HttpResponseRedirect(reverse_lazy('forum:user_detail', kwargs={'pk': self.request.user.id}))
forms.py
class PostForm(ModelForm):
class Meta:
model = Post
fields = ['category', 'title', 'text']
tests.py
def test_post_form_create_should_pass(self):
# this dict is in setUp() as well as the test_category but for simplicity I will include it in this method
post_data = {
'category': self.test_category.pk,
'title': 'test_post',
'text': 'test_post_text'
}
post_count = Post.objects.count()
form = PostForm(data=self.post_data)
self.assertTrue(form.is_valid())
form.save()
self.assertEqual(post_count + 1, Post.objects.count())
如有任何帮助,我们将不胜感激!
您只是在测试表单。所以在你的测试中调用视图函数是没有意义的。在您的测试中保存表单之前,您应该使用 form.instance.user = ...
手动将用户分配给表单的实例,因为这是应该使用表单的方式。
此外,您应该通过实际登录用户并将请求发布到 PostCreate
视图来测试您的视图。您在此处测试视图是否正确保存了表单(并且您的 form_valid()
方法是否正常工作)。
注意:post.user = self.request.user
比使用 id
从数据库中重新获取用户要好。这是多余的。