• 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()方法。

    这样重构后测试通过

  • 相关阅读:
    jQuery源码的一个坑
    读书笔记-你不知道的JS上-混入与原型
    读书笔记-你不知道的JS上-对象
    读书笔记-你不知道的JS上-this
    读书笔记-你不知道的JS上-闭包与模块
    读书笔记-你不知道的JS上-声明提升
    读书笔记-你不知道的JS上-函数作用域与块作用域
    读书笔记-你不知道的JS上-词法作用域
    oracle高水位
    Java开发5个JDK工具
  • 原文地址:https://www.cnblogs.com/ranxf/p/11691462.html
Copyright © 2020-2023  润新知