Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError: get_form() got an unexpected keyword argument 'form_class' with Django 1.8.2 #78

Closed
woostersoz opened this issue Jun 27, 2015 · 7 comments

Comments

@woostersoz
Copy link

I have installed the latest version of Mongonaut with Django 1.8.2. While I am able to login and view the data from my Mongo DB, I get the following error whenever I try to Add or Edit any data:

TypeError: get_form() got an unexpected keyword argument 'form_class'

This is the traceback. Any help would be appreciated!

Traceback (most recent call last):
File "/home/abc/workspace/3m/ve/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response
response = wrapped_callback(request, _callback_args, *_callback_kwargs)
File "/home/abc/workspace/3m/ve/local/lib/python2.7/site-packages/django/views/generic/base.py", line 71, in view
return self.dispatch(request, _args, *_kwargs)
File "/home/abc/workspace/3m/ve/local/lib/python2.7/site-packages/django/views/generic/base.py", line 89, in dispatch
return handler(request, _args, *_kwargs)
File "/home/abc/workspace/3m/ve/local/lib/python2.7/site-packages/django/views/generic/edit.py", line 206, in get
form = self.get_form()
File "/home/abc/workspace/3m/ve/local/lib/python2.7/site-packages/django/views/generic/edit.py", line 36, in get_form_with_form_class
return get_form(self, form_class=form_class)
TypeError: get_form() got an unexpected keyword argument 'form_class'

@garrypolley
Copy link
Collaborator

@woostersoz Is it possible for you to add the code that is creating the error as well? When does this occur? Is this when the application is first started? What does the existing configuration look like?

Personally I've not tried this project on Django 1.8 yet so I can mostly provide general debugging support right now.

@woostersoz
Copy link
Author

Thanks, @garrypolley. As I mentioned earlier, this error specifically takes place when I try to 'Add' or 'Edit' any of the data that I have exposed to Mongonaut. The Django related code I wrote for this is below.

mmm/mongoadmin.py

from mongonaut.sites import MongoAdmin

from authentication.models import CustomUser, Company

class UserAdmin(MongoAdmin):
    search_fields = ('first_name', 'last_name', 'email')
    list_fields = ('first_name', 'last_name', 'email')

    def has_edit_permission(self, request):
        return request.user.is_superadmin

    def has_add_permission(self, request):
        return request.user.is_superadmin

CustomUser.mongoadmin = UserAdmin()

class CompanyAdmin(MongoAdmin):
    search_fields = ('name')
    list_fields = ('name')

    def has_edit_permission(self, request):
        return request.user.is_superadmin

    def has_add_permission(self, request):
        return request.user.is_superadmin

Company.mongoadmin = UserAdmin()

@garrypolley
Copy link
Collaborator

Just a note, it seems like this line:

CustomUser.mongoadmin = UserAdmin()

Is repeated twice and not properly assigning the CompanyAdmin. This isn't necessarily related to the issue at hand, but I thought I'd mention it.

Actually relevant bit

Looking into this more this seems to be related to this commit in Django:

django/django@f2ddc43 (I could be wrong)

What it looks like is that this added code:

https://github.com/django/django/blob/1.8.2/django/views/generic/edit.py#L19-L37

Is doing some kind of validation on the form class that is used.

Related to the django-mongonaut code it seems like we need to change our arguments to be keyword based like newer Django. This may however, cause some compatibility issues. I don't have the time now to look into all the details but this is what I've noticed so far.

These two spots in our code:

Have a signature of:

def get_form(self, Form):
    # code

Which means they expect an argument passed that is the Form object. Looking at the newer Django code it now expects:

def get_form(self, form_class=None):
    # code

So the newer one expects a keyword argument instead of an ordered argument. The older 1.7 line had this signature:

def get_form(self, form_class):
    # code

This means that the previous code required the argument and it was not an ordered argument.

When I read the release notes related to the other 1.8 commit it specifically says:

FormMixin subclasses that override the get_form() method should make sure to provide a default value for the form_class argument since it's now optional.

This leads me to believe we need to change our method signature on the get_form for DocumentAddFormView and DocumentEditFormView.

Sadly I do not have the time to test this right now. If someone could test this out and submit a pull request that fixes the 1.8 line and is compatible with the previous Django then that would be awesome!

Thanks for the report and hopefully this long rambling comment helps out.

@woostersoz
Copy link
Author

Thanks @garrypolley - I made the changes to the signatures within the 2 form views and it seems to work now - brilliant!

Unfortunately, I don't know enough about checking the compatibility of this fix with earlier versions of Django :( But thanks again for your help in identifying the specific places where it needed to be applied.

dmarcelino added a commit to dmarcelino/django-mongonaut that referenced this issue Jul 20, 2016
@dmarcelino
Copy link

@woostersoz, can you share your code changes?

I've tried the fix at dmarcelino@c23e418 with django 1.9.8 but now I'm getting another error: getattr(): attribute name must be string

Environment:


Request Method: GET
Request URL: http://localhost:8000/mongonaut/myapp/myClass/578f916e19ad8611087c241a/edit/

Django Version: 1.9.8
Python Version: 3.5.1
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'myapp',
 'django_mongoengine',
 'django_mongoengine.mongo_auth',
 'django_mongoengine.mongo_admin.sites',
 'django_mongoengine.mongo_admin',
 'mongonaut']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware']



Traceback:

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  149.                     response = self.process_exception_by_middleware(e, request)

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
  147.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/django/views/generic/base.py" in view
  68.             return self.dispatch(request, *args, **kwargs)

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/django/views/generic/base.py" in dispatch
  88.         return handler(request, *args, **kwargs)

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/django/views/generic/edit.py" in get
  213.         return self.render_to_response(self.get_context_data())

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/mongonaut/views.py" in get_context_data
  235.         context = super(DocumentEditFormView, self).get_context_data(**kwargs)

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/mongonaut/mixins.py" in get_context_data
  50.         context = super(MongonautViewMixin, self).get_context_data(**kwargs)

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/django/views/generic/edit.py" in get_context_data
  122.             kwargs['form'] = self.get_form()

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/mongonaut/views.py" in get_form
  271.             self.form = MongoModelForm(model=self.document_type, instance=self.document).get_form()

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/mongonaut/forms/forms.py" in get_form
  71.         self.set_fields()

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/mongonaut/forms/forms.py" in set_fields
  45.         self.set_form_fields(form_field_dict)

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/mongonaut/forms/form_mixins.py" in set_form_fields
  173.                 default_value = self.get_field_value(form_key)

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/mongonaut/forms/form_mixins.py" in get_field_value
  276.             return get_value(self.model_instance, field_key)

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/mongonaut/forms/form_mixins.py" in get_value
  271.                 return_data = (document._data.get(None, None) if current_key == "id" else

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/mongoengine/base/datastructures.py" in get
  393.             return self[key]

File "/Users/mycomputer/.virtualenvs/myproject/lib/python3.5/site-packages/mongoengine/base/datastructures.py" in __getitem__
  380.             return getattr(self, key)

Exception Type: TypeError at /mongonaut/myapp/myClass/578f916e19ad8611087c241a/edit/
Exception Value: getattr(): attribute name must be string

Being a newb to both django and django-mongonaut doesn't help so any pointers are welcomed. Thanks!

@garrypolley
Copy link
Collaborator

Not sure what is exactly wrong but it looks like maybe this line should be updated to no longer pass None, None?

https://github.com/jazzband/django-mongonaut/blob/master/mongonaut/forms/form_mixins.py#L271-L272

I'm not sure though. It looks like It is failing when making the document._data.get(None,None) call which I think is a direct call to a private object inside MongoEngine.

What version of MongoEngine is running with that code?

@dmarcelino
Copy link

What version of MongoEngine is running with that code?

mongoengine 0.10.6

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants