英文:
Get form-data for Django tests
问题
我想测试一个Django表单,而不必亲自拼写所有通常会进入其中的POST数据。
在一个真实的应用中,这些数据将由浏览器提供,基于Django渲染的表单(作为HTML)。
如何在不通过浏览器的情况下获取这些数据?
form0 = MyForm(instance=obj) # 在正常使用中显示的表单
data = the_magic_function(form0) # 如果用户立即按提交键,将被提交的数据
# 可能会操纵数据的某些部分以使测试更有趣
form1 = MyForm(instance=obj, data=data)
# 实际的测试在form1上进行
form.initial
有点像我要找的,但不完全是:它包含Python对象而不是字符串。
英文:
I would like to test a Django form, without spelling out myself all the POSTed data that would normally go into it.
In a real application, this data would be provided by the browser, based on the form as rendered (as HTML) by Django.
How do I get the data without going through the browser?
form0 = MyForm(instance=obj) # form which would be shown in normal usage
data = the_magic_function(form0) # data which would be posted if user just pressed submit right away
# potentially manipulate some parts of this data to make the test interesting
form1 = MyForm(instance=obj, data=data)
# actual tests are on form1
form.initial
is kinda what I'm looking for, but not quite: it contains Python objects rather than strings.
答案1
得分: 1
这不完全是你所要求的,但这段代码片段可能仍然对你有所帮助。我将其用于从表单响应创建新的POST数据。例如,当表单验证失败时,重新提交已校正的表单。
import lxml.html
def form_data(response: HttpResponse, **kwargs) -> dict:
return parse_html_form(response.content, **kwargs)
def parse_html_form(html: str, **kwargs) -> dict:
"""将表单数据返回为字典。
通过使用`kwargs`中的属性来筛选表单查找。
"""
tree = lxml.html.fromstring(html)
filter = " and ".join(f"@{key}='{val}'" for key, val in kwargs.items())
form = tree.xpath(f"//form[{filter}]" if filter else "//form")[0]
data = {}
for key, element in form.inputs.items():
match element.value:
case lxml.html.CheckboxValues():
data[key] = [sub.value for sub in element.value.group if sub.value]
case lxml.html.MultipleSelectOptions():
data[key] = list(element.value)
case _:
data[key] = element.value or ""
return data
你可以在渲染的表单上使用它:
form0 = MyForm(instance=obj)
data = parse_from_html(form0.as_div())
英文:
It's not exactly what you asked for, but this code snippet might help you nonetheless. I use it for creating new POST data from a form response. For example, to resubmit the corrected form when the form validation failed.
import lxml.html
def form_data(response: HttpResponse, **kwargs) -> dict:
return parse_html_form(response.content, **kwargs)
def parse_html_form(html: str, **kwargs) -> dict:
"""Returns form data as a dict.
The form lookup can be narrowed down by using attributes to filter for
as `kwargs`.
"""
tree = lxml.html.fromstring(html)
filter = " and ".join(f"@{key}='{val}'" for key, val in kwargs.items())
form = tree.xpath(f"//form[{filter}]" if filter else "//form")[0]
data = {}
for key, element in form.inputs.items():
match element.value:
case lxml.html.CheckboxValues():
data[key] = [sub.value for sub in element.value.group if sub.value]
case lxml.html.MultipleSelectOptions():
data[key] = list(element.value)
case _:
data[key] = element.value or ""
return data
You could use it on the rendered form:
form0 = MyForm(instance=obj)
data = parse_from_html(form0.as_div())
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论