[Django] #26654: Better forms for django.contrib.postgres.fields

73 views
Skip to first unread message

Django

unread,
May 23, 2016, 8:03:02 AM5/23/16
to django-...@googlegroups.com
#26654: Better forms for django.contrib.postgres.fields
-------------------------+-------------------------------------------------
Reporter: | Owner:
primal100 |
Type: New | Status: new
feature |
Component: | Version: master
contrib.postgres | Keywords: postgres, array, hstore, json,
Severity: Normal | forms
Triage Stage: | Has patch: 1
Unreviewed |
Easy pickings: 0 | UI/UX: 0
-------------------------+-------------------------------------------------
I'm working on a pull request which provides the following features to
django.contrib.postgres:

django.contrib.postgres.fields.array.ArrayField:

1) Currently the Array Field uses a SimpleArrayField. New feature is to
accepts a form_size argument in which case a Split Array Field will be
used.

2) If the choices argument is given to an ArrayField, the choices would
now expect to be of the BaseField Type and a TypedMultipleChoiceField will
be used. The array value will be composed of the choices given in this
field.

django.contrib.postgres.forms.nested_form:

1) A NestedFormWidget and NestedFormField (subclassed from MultiWidget and
MultiValueField) which can be used to create a nested form. Unlike with
MultiWidget, each widget has a label and the widgets are presented in list
form. The form compress and widget decompress methods work with data as a
dictionary of field names and values.

The NestedFormField accept either a list of tuples, with each tuple
containing a field name and field instance, or a tuple of field names
("keys" keyword argument), in which case the NestedForm will consist of a
charfield for each given field name.

NestedFormFields can contain other NestedFormFields.

django.contrib.postgres.fields.hstore.HStoreField:

1) Now accepts a "fields" keyword argument which is the same format as the
NestedFormField fields keyword argument. If given, a NestedFormField will
be used consisting of the given fields. The NestedFormField will return a
dictionary which can then be used to populate the HStore Field. The fields
argument should only contain field types which have string values.

2) Accepts a keys argument. If given a NestedFormField will be created
consisting only of CharFields, one for each key.

3) Accepts a require_all_fields argument in which case all fields in the
NestedForm will be required (default is False).

4) Accepts a max_value_length argument - if given with the keys argument,
this will be the max length of each CharField.

JSONField:

1) Now accepts a "fields" keyword argument which is the same format as the
NestedFormField fields keyword argument. If given, a NestedFormField will
be used consisting of the given fields. The NestedFormField will return a
dictionary which can then be used to populate the JSON Field. The fields
can consist of any form field types, including another NestedFormField or
a SplitArrayField.

2) Accepts a require_all_fields argument in which case all fields in the
NestedForm will need to be not blank (default is False).

I've written the first revision of the patch and also tests in
tests.postgres_tests. All the above features have been verified. This
includes some Selenium tests. I need to start working on documentation but
I will upload a branch today.

Would love to have some feedback on what people think of these features.

Example usage:

{{{
#!python
class Product(models.Model):
name = models.CharField(max_length=15)
keywords = ArrayField(models.CharField(max_length=20), default=[],
form_size=10, blank=True)
sports = ArrayField(models.IntegerField(),default=[], blank=True,
choices=(
(0, 'Football'), (1, 'Tennis'), (2, 'Golf'), (3, 'Basketball'),
(4, 'Hurling'), (5, 'Baseball')))
shipping = HStoreField(keys=('Address', 'City', 'Region', 'Country'),
blank=True, default={})
details = JSONField(blank=True, default={}, fields=(
('Brand', NestedFormField(keys=('Name', 'Country'))),
('Type', forms.CharField(max_length=25, required=False)),
('Colours',
SplitArrayField(base_field=forms.CharField(max_length=10, required=False),
size=10)),
)
)

def __str__(self):
return self.name
}}}

I will attach an image showing how the above would look in the admin add
form.

--
Ticket URL: <https://code.djangoproject.com/ticket/26654>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
May 23, 2016, 8:03:45 AM5/23/16
to django-...@googlegroups.com
#26654: Better forms for django.contrib.postgres.fields
-------------------------------------------------+-------------------------
Reporter: primal100 | Owner:
Type: New feature | Status: new
Component: contrib.postgres | Version: master
Severity: Normal | Resolution:
Keywords: postgres, array, hstore, json, | Triage Stage:
forms | Unreviewed
Has patch: 1 | Easy pickings: 0
UI/UX: 0 |
-------------------------------------------------+-------------------------
Changes (by primal100):

* Attachment "admin.jpg" added.

How the Product model would look in the admin add view

Django

unread,
May 23, 2016, 10:22:20 AM5/23/16
to django-...@googlegroups.com
#26654: Better forms for django.contrib.postgres.fields
-------------------------------------+-------------------------------------
Reporter: primal100 | Owner: primal100
Type: New feature | Status: assigned

Component: contrib.postgres | Version: master
Severity: Normal | Resolution:
Keywords: postgres, array, | Triage Stage:
hstore, json, forms | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0

Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by primal100):

* status: new => assigned
* needs_better_patch: => 0
* owner: => primal100
* needs_tests: => 0
* needs_docs: => 0


--
Ticket URL: <https://code.djangoproject.com/ticket/26654#comment:1>

Django

unread,
May 24, 2016, 4:12:19 AM5/24/16
to django-...@googlegroups.com
#26654: Better forms for django.contrib.postgres.fields
-------------------------------------+-------------------------------------
Reporter: primal100 | Owner: primal100
Type: New feature | Status: assigned
Component: contrib.postgres | Version: master
Severity: Normal | Resolution:
Keywords: postgres, array, | Triage Stage:
hstore, json, forms | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------

Comment (by mjtamlyn):

Two main problems I have with this:

- That level of form declaration does not belong in the model. Even if we
have form fields capable of this, we should define them as form fields.
- These declarations imply to me a concrete specification of what your
data looks like. This begs the question - why would you use an HStore or a
JSON field in that case anyway?

--
Ticket URL: <https://code.djangoproject.com/ticket/26654#comment:2>

Django

unread,
May 24, 2016, 8:43:17 AM5/24/16
to django-...@googlegroups.com
#26654: Better forms for django.contrib.postgres.fields
-------------------------------------+-------------------------------------
Reporter: primal100 | Owner: primal100
Type: New feature | Status: closed
Component: contrib.postgres | Version: master
Severity: Normal | Resolution: needsinfo

Keywords: postgres, array, | Triage Stage:
hstore, json, forms | Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by timgraham):

* status: assigned => closed
* resolution: => needsinfo


Comment:

I raised similar concerns on the [https://groups.google.com/d/topic
/django-developers/BByaPG39iw8/discussion django-developers thread]. I
think we also need separate tickets for each enhancement (if the
discussion yields consensus to move forward with any of the proposals)
rather than a single ticket.

--
Ticket URL: <https://code.djangoproject.com/ticket/26654#comment:3>

Reply all
Reply to author
Forward
0 new messages