如何使用测试客户端填写 Django 表单

Posted

技术标签:

【中文标题】如何使用测试客户端填写 Django 表单【英文标题】:How to fill a Django form using test Client 【发布时间】:2018-10-12 18:59:18 【问题描述】:

我想测试我的 Django 表单,但我收到了这个错误

django.core.exceptions.ValidationError: ['ManagementForm data is missing or has been tampered with']

这样做:

 self.client.post(self.url, "title" : 'title', "status" : 2, "user" :1)

而我的模型只需要那些字段...

谢谢你:)

编辑 1: 这是表格:

class ArticleAdminDisplayable(DisplayableAdmin):

    fieldsets = deepcopy(ArticleAdmin.fieldsets)
    list_display = ('title', 'department', 'publish_date', 'status', )
    exclude = ('related_posts',)
    filter_horizontal = ['categories',]
    inlines = [ArticleImageInline,
               ArticlePersonAutocompleteInlineAdmin,
               ArticleRelatedTitleAdmin,
               DynamicContentArticleInline,
               ArticlePlaylistInline]
    list_filter = [ 'status', 'keywords', 'department', ]

class ArticleAdmin(admin.ModelAdmin):

    model = Article

关于文章模型,继承太多,所以您必须相信我,(模型)需要的唯一字段是标题、状态和用户。

【问题讨论】:

你的表单是什么样子的? 只有这一行:型号 = 文章。而文章模型只需要一个标题、一个状态和一个用户.. 你能显示你的模型和表格的代码吗?从您的测试数据来看,“状态”和“用户”都是整数字段 这里是一个示例,如何从response.content 解析表单,然后将数据与 Django TestClient 一起使用:***.com/a/65603777/633961 【参考方案1】:

好的,所以从您的form 来看,您有很多正在使用的 django 插件。我应该要求您提供完整的test,但我想我可能明白其中一些问题出在哪里。

当您self.client.post 时,您实际上是在检查view 而不一定是表单。 "title" : 'title', "status" : 2, "user" :1 是您的 clientposting 的 3 个值。

Input Field : Data(Value of the Field)
title       :'title'  # A string
status      : 2       # The number 2
user        : 1       # The number 1

这里有一些对我有用的测试代码。希望对您有所帮助。

forms.py

from .models import CustomerEmployeeName


class EmployeeNameForm(ModelForm):

    class Meta:
        model = CustomerEmployeeName
        fields = [
            'employee_choices',
            'first_name',
            'middle_name',
            'last_name',
            ]

test_forms.py

from django.test import TestCase

from .forms import EmployeeNameForm

class TestEmployeeNameForm(TestCase):
    """
    TESTS: form.is_valid
    """
    # form.is_valid=True
    # middle_name not required.
    # middle_name is blank.
    def test_form_valid_middle_optional_blank(self):
        name_form_data = 'first_name': 'First',     # Required
                            'middle_name': '',       # Optional
                            'last_name': 'Last',     # Required
                            'employee_choices': 'E', # Required
                        
        name_form = EmployeeNameForm(data=name_form_data)

        self.assertTrue(name_form.is_valid())

view.py

from .forms import EmployeeNameForm

def create_employee_profile(request):

    if request.POST:
        name_form = EmployeeNameForm(request.POST)

        if name_form.is_valid():
            new_name_form = name_form.save()
            return redirect(new_name_form) #get_absolute_url set on model

        else:
            return render(request,
                'service/template_create_employee_profile.html',
                    'name_form': name_form
                    )

    else:
        name_form = EmployeeNameForm(
                        initial='employee_choices': 'E'
                        )
        return render(request,
                'service/template_create_employee_profile.html',
                'name_form': name_form
                )

test_views.py

from django.test import TestCase, Client

from service.models import CustomerEmployeeName

class TestCreateEmployeeProfileView(TestCase):
    # TEST: View saves valid object.
    def test_CreateEmployeeProfileView_saves_valid_object(self):
        response = self.client.post(
            '/service/', 
                    'first_name': 'Test',        # Required
                    'middile_name': 'Testy',     # Optional
                    'last_name': 'Testman',      # Required
                    'employee_choices': 'E',     # Required
                    )

        self.assertTrue(CustomerEmployeeName.objects.filter(
            first_name='Test').exists())

如果您想发布更多代码,我会很乐意查看。

【讨论】:

实际上,我要做的就是使用 client.post() 测试“前端”表单。你的代码让我觉得我的错误可能来自我表单中的“内联”字段。你知道如何处理这个字段吗? 你使用的是什么 Django 包?我不知道您的“内联”字段需要什么,尽管根据您的列表判断,它看起来有 5 个值。 我在 Django 1.9 上使用mezzanine module。这 5 个值是我的 admin.py 的其他形式 我没用过夹层。用户和状态输入是否应该是整数? 是的,关于状态。关于用户,形式是 yes,在模型中 nope !【参考方案2】:

表单集需要有自己的ManagementForm

看看this website 和this post 为您指明正确的方向。

【讨论】:

如果我想模拟 POST 查询,必须要有一个表单集吗?

以上是关于如何使用测试客户端填写 Django 表单的主要内容,如果未能解决你的问题,请参考以下文章

在django中将注册表单填写到数据库后如何存储用户选择的单选按钮值?

如何在 Django 中使用 FileField 测试表单?

如何在 Django 中创建一个分为两部分的注册表单,这样一个电话只有在电子邮件验证后才能填写第二部分?

如何在 django 中查找会话是不是已过期

如何在客户端应用程序中使用 Django 模型进行验证和表单生成?

Django,如何在提交表单时将 HTML 表单值传递给 URL?