Django学习系列15:把POST请求中的数据存入数据库
要修改针对首页中的POST请求的测试。希望视图把新添加的待办事项存入数据库,而不是直接传给响应。
为了测试这个操作,要在现有的测试方法test_can_save_a_post_request中添加3行新代码
# lists/tests.py def test_can_save_a_post_request(self): response = self.client.post('/', data={'item_text':'A new list item'}) self.assertEqual(Item.objects.count(), 1) # 1 new_item = Item.objects.first() # 2 self.assertEqual(new_item.text, 'A new list item') # 3 self.assertIn('A new list item', response.content.decode()) self.assertTemplateUsed(response, 'home.html')
代码解析:
1、检查是否把一个新Item对象存入数据库,objects.count()是objects.all().count()的简写形式
2、objects.first()等价于objects.all()[0]
3、检查待办事项的文本是否正确。
再次运行测试
self.assertEqual(Item.objects.count(), 1) # 1 AssertionError: 0 != 1
修改一下视图
from django.shortcuts import render from lists.models import Item from django.http import HttpResponse # Create your views here.在这儿编写视图 def home_page(request): item = Item() item.text = request.POST.get('item_text', '') item.save() return render(request, 'home.html', { 'new_item_text': request.POST.get('item_text', ''), })
单元测试……通过了。
审视一下前面的代码,或许能发现一些明显的问题或需要注意的:
1、不要每次请求都保存空白的待办事项
2、post请求的测试太长
3、在表格中显示多个待办事项
4、支持多个清单!
代码重构
解决单元测试一次只测试一件事,在现有代码中添加一个断言,定义一个新的测试方法
# lists/tests.py class HomePageTest(TestCase): 【……】 def test_only_saves_items_when_necessary(self): self.client.get('/') self.assertEqual(Item.objects.count(), 0)
这个测试得到AssertionError: 1 != 0失败
下面来修正这个问题,注意,虽然对视图函数的逻辑改动幅度很小,但代码实现方式有细微的变动。
from django.shortcuts import render from lists.models import Item from django.http import HttpResponse # Create your views here.在这儿编写视图 def home_page(request): if request.method == 'POST': new_item_text = request.POST['item_text'] # 1 Item.objects.create(text=new_item_text) # 2 else: new_item_text = '' # 1 return render(request, 'home.html', { 'new_item_text': new_item_text, # 1 })
代码解析:
#1 使用名为 new_item_text的变量,其值是POST请求中的数据,或者空字符串。
#2 .objects.create()是创建新Item对象的简化方式,无需在调用.save()方法。
这样重构后测试通过