danni / django-postgres-composite-types

Postgres composite types support for Django
BSD 3-Clause "New" or "Revised" License
51 stars 13 forks source link

Fix rendering of null values in widget #24

Closed mumumumu closed 5 years ago

mumumumu commented 5 years ago

I've run into this error when trying to render null composite fields in the admin:

Traceback (most recent call last):
  File "/projects/django-postgres-composite-types/tests/test_forms.py", line 123, in test_null_initial_data
    str(form['simple_field']))
  File "/projects/django-postgres-composite-types/.tox/py36-dj1.11/lib/python3.6/site-packages/django/utils/html.py", line 394, in <lambda>
    klass.__str__ = lambda self: mark_safe(klass_str(self))
  File "/projects/django-postgres-composite-types/.tox/py36-dj1.11/lib/python3.6/site-packages/django/forms/boundfield.py", line 41, in __str__
    return self.as_widget()
  File "/projects/django-postgres-composite-types/.tox/py36-dj1.11/lib/python3.6/site-packages/django/forms/boundfield.py", line 127, in as_widget
    **kwargs
  File "/projects/django-postgres-composite-types/.tox/py36-dj1.11/lib/python3.6/site-packages/django/forms/widgets.py", line 220, in render
    context = self.get_context(name, value, attrs)
  File "/projects/django-postgres-composite-types/postgres_composite_types/forms.py", line 204, in get_context
    value.get(subname),
AttributeError: 'NoneType' object has no attribute 'get'

I've added a simple fix to return an empty dict when the value of the field is null in the CompositeTypeField to prevent the widget from breaking.

mumumumu commented 5 years ago

This is when I try to simply render a composite field in the Django admin.

@admin.register(Organization)
class OrganizationAdmin(ModelAdmin):
    fields = (
        'name',
        'address',
    )

My model & composite type are defined as:

class CompositeAddress(CompositeType):
    address1 = models.CharField(blank=True, max_length=200)
    address2 = models.CharField(blank=True, max_length=200)
    city = models.CharField(blank=True, max_length=200)
    state = USStateField(blank=True)
    zip_code = USZipCodeField(blank=True)

    class Meta:
        db_type = 'composite_address'

class Organization(Model):
    name = models.CharField(max_length=200)
    address = CompositeAddress.Field(blank=True, null=True)
danni commented 5 years ago

Interesting, I don't think I've ever tried using this with the admin actually. Thanks.