jrief / django-angular

Let AngularJS play well with Django
http://django-angular.awesto.com/
MIT License
1.23k stars 294 forks source link

Avoid modifying form __init__ signature #259

Closed omarkhan closed 7 years ago

omarkhan commented 8 years ago

Background

I am trying to use django-angular's NgFormValidationMixin with django's built-in AuthenticationForm. This is the code I am using:

class LoginForm(NgFormValidationMixin, AuthenticationForm,
                metaclass=NgDeclarativeFieldsMetaclass):
    pass

When using this with django's built-in login view, I get the following error:

Traceback (most recent call last):
  File "/home/vagrant/.virtualenvs/opencraft/lib/python3.5/site-packages/djng/forms/angular_base.py", line 280, in non_field_errors
    errors = super(NgFormBaseMixin, self).non_field_errors()
  File "/home/vagrant/.virtualenvs/opencraft/lib/python3.5/site-packages/django/forms/forms.py", line 289, in non_field_errors
    return self.errors.get(NON_FIELD_ERRORS, self.error_class(error_class='nonfield'))
  File "/home/vagrant/.virtualenvs/opencraft/lib/python3.5/site-packages/django/forms/forms.py", line 153, in errors
    self.full_clean()
  File "/home/vagrant/.virtualenvs/opencraft/lib/python3.5/site-packages/django/forms/forms.py", line 362, in full_clean
    self._clean_fields()
  File "/home/vagrant/.virtualenvs/opencraft/lib/python3.5/site-packages/django/forms/forms.py", line 374, in _clean_fields
    value = field.widget.value_from_datadict(self.data, self.files, self.add_prefix(name))
  File "/home/vagrant/.virtualenvs/opencraft/lib/python3.5/site-packages/django/forms/widgets.py", line 231, in value_from_datadict
    return data.get(name)
AttributeError: 'WSGIRequest' object has no attribute 'get'

I did some digging and it turns out that django's login view passes a request argument to the form constructor. This breaks the NgFormBaseMixin constructor, which expects data as the first positional argument.

Proposal

This pull request modifies NgFormBaseMixin.__init__ and NgModelFormMixin.__init__ to not care about the __init__ signature of the form they are mixin in with. This is accomplished by calling the superclass constructor first, then manipulating self.data.

jrief commented 7 years ago

Thank @omarkhan for the reminder on this PR. Do you have any preference what I shall add to the changelog?

antoviaque commented 7 years ago

@jrief Answering for @omarkhan since he is not working with us (OpenCraft) on this anymore - no specific preference no - something among the lines of "Allow to use form mixins (like NgFormValidationMixin) with django's built-in AuthenticationForm"?

jrief commented 7 years ago

I'll release this together with PR #260 as version 0.8.5 as soon as I get the OK for it.