代码之家  ›  专栏  ›  技术社区  ›  muhuk

如果只提供HTML源代码,如何提交表单?

  •  0
  • muhuk  · 技术社区  · 17 年前

    HTML源(字符串) . 换句话说,我至少需要生成POST参数的能力 . 这在Django项目的单元测试中是必需的。我想要一个可能的解决方案;

    • 仅使用标准Python库和Django。
    • 如果存在多个表单,则允许从特定表单生成参数。
    • 允许我在提交前更改值。

    从给定表单类返回(Django)表单实例的解决方案是最好的。因为它允许我使用验证。理想情况下,它将使用源(字符串)、表单类和可选的表单名称,并返回呈现前的实例。

    注:我知道这不是一项容易的任务,可能取得的成果很难证明所需的努力是合理的。但我只是好奇如何以一种实用可靠的方式做到这一点。如果可能的话。

    4 回复  |  直到 17 年前
        1
  •  4
  •   Justin Voss    17 年前

    你应该重读这本书 documentation about Django's testing framework ,特别是关于使用测试视图(和窗体)的部分 the test client .

    GET 和 POST 对Django视图的请求。您可以读取响应HTML或获得相同的响应 Context 对象指定接收到的模板。你的 上下文 对象应包含实际的 forms.Form 您正在寻找的实例。

    例如,如果您在URL上查看 /form/ 传递上下文 {'myform': forms.Form()}

    from django.test.client import Client
    c = Client()
    
    # request the web page:
    response = c.get('/form/')
    
    # get the Form object:
    form = response.context['myform']
    
    form_data = form.cleaned_data
    my_form_data = {} # put your filled-out data in here...
    form_data.update(my_form_data)
    
    # submit the form back to the web page:
    new_form = forms.Form(form_data)
    if new_form.is_valid():
        c.post('/form/', new_form.cleaned_data)
    

    希望这能实现您想要的,而不必麻烦解析HTML。

    编辑 :在我重新阅读Django文档中关于表单的内容后,发现表单是不可变的。没关系,不过,创建一个新的 Form 举例并提交;我修改了我的代码示例以匹配这一点。

        2
  •  2
  •   S.Lott    17 年前

    是否要测试具有表单的Django应用程序?

    • 在这种情况下,您需要执行初始GET
    • 然后是产生的帖子

    下面是我们如何使用表单测试Django应用程序。

    class Test_HTML_Change_User( django.test.TestCase ):
        fixtures = [ 'auth.json', 'someApp.json' ]
        def test_chg_user_1( self ):
            self.client.login( username='this', password='this' )
            response= self.client.get( "/support/html/user/2/change/" )
            self.assertEquals( 200, response.status_code )
            self.assertTemplateUsed( response, "someApp/user.html")
    
    def test_chg_user( self ):
        self.client.login( username='this', password='this' )
        # The truly fussy would redo the test_chg_user_1 test here
        response= self.client.post(
            "/support/html/user/2/change/",
            {'web_services': 'P',
             'username':'olduser',
             'first_name':'asdf',
             'last_name':'asdf',
             'email':'asdf@asdf.com',
             'password1':'passw0rd',
             'password2':'passw0rd',} )
        self.assertRedirects(response, "/support/html/user/2/" )
        response= self.client.get( "/support/html/user/2/" )
        self.assertContains( response, "<h2>Users: Details for", status_code=200 )
        self.assertContains( response, "olduser" )
        self.assertTemplateUsed( response, "someApp/user_detail.html")
    

        3
  •  2
  •   PhiLho    17 年前

    这很简单。。。同时也很难。
    免责声明:我对Python知之甚少,对Django一无所知。。。所以我给出了一般的,语言不可知论的建议。。。 如果上述建议之一不适用于您,您可能需要手动执行:

    • 使用HTML解析器加载页面,列出表单。
    • 如果 method 属性为POST(不区分大小写),则获取 action 属性获取请求的URL(可以是相对的)。
    • 在表单中,获取所有 input 和 select 标签。这个 name id 如果没有名称,则属性是请求参数的键。这个 value
    • 对于 选择 ,则该值为所选值之一 option 或者显示的文本为“否” 属性

    嗯。

        4
  •  0
  •   Daniel Naab    17 年前

    退房 mechanize 或者是包装纸 twill . 我想是的 ClientForm 模块将为您工作。