archesproject/arches

Creating spatial view in django admin with empty attributenodes fails with TypeError

Closed this issue · 2 comments

  • Log in to the django admin
  • Add a spatial view, specifying a geometry node but leaving attributenodes as "null"
  • Save

Essentially, clean() runs even if the form fields have failed validation (e.g. might have None in them).

Result:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/admin/models/spatialview/add/


Traceback (most recent call last):
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/core/handlers/exception.py", line 55, in inner
    response = get_response(request)
               ^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/core/handlers/base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/contrib/admin/options.py", line 718, in wrapper
    return self.admin_site.admin_view(view)(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/utils/decorators.py", line 188, in _view_wrapper
    result = _process_exception(request, e)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/utils/decorators.py", line 186, in _view_wrapper
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/views/decorators/cache.py", line 80, in _view_wrapper
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/contrib/admin/sites.py", line 241, in inner
    return view(request, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/contrib/admin/options.py", line 1961, in add_view
    return self.changeform_view(request, None, form_url, extra_context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/utils/decorators.py", line 48, in _wrapper
    return bound_method(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/utils/decorators.py", line 188, in _view_wrapper
    result = _process_exception(request, e)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/utils/decorators.py", line 186, in _view_wrapper
    response = view_func(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/contrib/admin/options.py", line 1820, in changeform_view
    return self._changeform_view(request, object_id, form_url, extra_context)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/contrib/admin/options.py", line 1865, in _changeform_view
    form_validated = form.is_valid()
                     ^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/forms/forms.py", line 197, in is_valid
    return self.is_bound and not self.errors
                                 ^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/forms/forms.py", line 192, in errors
    self.full_clean()
    ^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/forms/forms.py", line 327, in full_clean
    self._post_clean()
    ^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/forms/models.py", line 498, in _post_clean
    self.instance.full_clean(exclude=exclude, validate_unique=False)
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/jwalls/release/lib/python3.12/site-packages/django/db/models/base.py", line 1625, in full_clean
    self.clean()
    ^^^^^^^^^^^^
  File "/Users/jwalls/prj/arches/arches/app/models/models.py", line 2174, in clean
    node_ids = set(node["nodeid"] for node in self.attributenodes)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Exception Type: TypeError at /admin/models/spatialview/add/
Exception Value: 'NoneType' object is not iterable

cc/ @aj-he

@jacobtylerwalls - I though that blank=False and null=False would handle this?

attributenodes = JSONField(blank=False, null=False, db_column="attributenodes")

Form fields with invalid values don't prevent Model.clean() from running also. If you adjust how you're doing the check, and repeat the test, you'll see the Django admin surfaces those errors for blank=False.