5

I'd like to test my Django forms, but I got this error

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

doing this :

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

And my model only need those fields...

Thank you :)

EDIT 1: Here is the form :

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

About the article model there is too much inheritance so you've to trust me the only fields needed (by the model) are title, status and user.

AntoineLB
  • 482
  • 3
  • 19

2 Answers2

4

Okay, so judging by your form, you have a lot of django plugins that you are using. I should have asked for your full test, but I think I might understand where some of the problem is coming.

When you self.client.post, you are really checking the view and not necessarily the form. {"title" : 'title', "status" : 2, "user" :1} are 3 values that your client is posting.

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

Here's some test code that has worked for me. Hopefully it helps you.

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())

If you want to post more of your code I will be happy to look at it.

Carl Brubaker
  • 1,602
  • 11
  • 26
  • Actually, all I want to do is testing the "front" form, by using client.post(). And your code make me think that my error may come from the "inlines" field in my form. Do you know how to deal with this field ? – AntoineLB May 04 '18 at 08:07
  • What Django package are you using? I don’t know what your “inlines” field needs, although it looks like there are 5 values judging by your list. – Carl Brubaker May 04 '18 at 11:24
  • I'm on Django 1.9 and I'm using [mezzanine module](https://github.com/stephenmcd/mezzanine). The 5 values are other forms of my admin.py – AntoineLB May 04 '18 at 12:19
  • I haven’t used mezzanine. Are the user and status inputs supposed to be integers? – Carl Brubaker May 04 '18 at 14:46
  • Yes about status. About the user, in the form yes, in the model nope ! – AntoineLB May 04 '18 at 15:23
  • Sorry, I don’t think I know how to fix this – Carl Brubaker May 04 '18 at 16:51
0

Formsets need to have their ManagementForm.

Take a look at this website and this post to point you in the right direction.

Ralf
  • 16,086
  • 4
  • 44
  • 68