Enable CSV import for custom fields

This commit is contained in:
Jeremy Stretch 2020-01-29 14:29:47 -05:00
parent e6b018909d
commit 193435b554
3 changed files with 10 additions and 21 deletions

View File

@ -94,7 +94,7 @@ class CustomFieldModelCSVForm(CustomFieldModelForm):
# Append form fields # Append form fields
for cf in CustomField.objects.filter(obj_type=self.obj_type): for cf in CustomField.objects.filter(obj_type=self.obj_type):
field_name = 'cf_{}'.format(cf.name) field_name = 'cf_{}'.format(cf.name)
self.fields[field_name] = cf.to_form_field() self.fields[field_name] = cf.to_form_field(for_csv_import=True)
# Annotate the field in the list of CustomField form fields # Annotate the field in the list of CustomField form fields
self.custom_fields.append(field_name) self.custom_fields.append(field_name)

View File

@ -15,7 +15,7 @@ from django.utils.text import slugify
from taggit.models import TagBase, GenericTaggedItemBase from taggit.models import TagBase, GenericTaggedItemBase
from utilities.fields import ColorField from utilities.fields import ColorField
from utilities.forms import DatePicker, LaxURLField, StaticSelect2, add_blank_choice from utilities.forms import CSVChoiceField, DatePicker, LaxURLField, StaticSelect2, add_blank_choice
from utilities.utils import deepmerge, render_jinja2 from utilities.utils import deepmerge, render_jinja2
from .choices import * from .choices import *
from .constants import * from .constants import *
@ -282,12 +282,13 @@ class CustomField(models.Model):
return self.choices.get(pk=int(serialized_value)) return self.choices.get(pk=int(serialized_value))
return serialized_value return serialized_value
def to_form_field(self, set_initial=True, enforce_required=True): def to_form_field(self, set_initial=True, enforce_required=True, for_csv_import=False):
""" """
Return a form field suitable for setting a CustomField's value for an object. Return a form field suitable for setting a CustomField's value for an object.
set_initial: Set initial date for the field. This should be False when generating a field for bulk editing. set_initial: Set initial date for the field. This should be False when generating a field for bulk editing.
enforce_required: Honor the value of CustomField.required. Set to False for filtering/bulk editing. enforce_required: Honor the value of CustomField.required. Set to False for filtering/bulk editing.
for_csv_import: Return a form field suitable for bulk import of objects in CSV format.
""" """
initial = self.default if set_initial else None initial = self.default if set_initial else None
required = self.required if enforce_required else False required = self.required if enforce_required else False
@ -320,17 +321,19 @@ class CustomField(models.Model):
# Select # Select
elif self.type == CustomFieldTypeChoices.TYPE_SELECT: elif self.type == CustomFieldTypeChoices.TYPE_SELECT:
choices = [(cfc.pk, cfc.value) for cfc in self.choices.all()] choices = [(cfc.pk, cfc.value) for cfc in self.choices.all()]
# TODO: Accommodate bulk edit/filtering
# if not self.required or bulk_edit or filterable_only:
if not required: if not required:
choices = add_blank_choice(choices) choices = add_blank_choice(choices)
# Set the initial value to the PK of the default choice, if any # Set the initial value to the PK of the default choice, if any
if set_initial: if set_initial:
default_choice = self.choices.filter(value=self.default).first() default_choice = self.choices.filter(value=self.default).first()
if default_choice: if default_choice:
initial = default_choice.pk initial = default_choice.pk
field = forms.TypedChoiceField(
choices=choices, coerce=int, required=required, initial=initial, widget=StaticSelect2() field_class = CSVChoiceField if for_csv_import else forms.ChoiceField
field = field_class(
choices=choices, required=required, initial=initial, widget=StaticSelect2()
) )
# URL # URL

View File

@ -442,20 +442,6 @@ class CSVChoiceField(forms.ChoiceField):
return self.choice_values[value] return self.choice_values[value]
class CSVCustomFieldChoiceField(forms.TypedChoiceField):
"""
Invert the choice tuples: CSV import takes the human-friendly label as input rather than the database value
"""
def __init__(self, *args, **kwargs):
if 'choices' in kwargs:
kwargs['choices'] = {
label: value for value, label in kwargs['choices']
}
super().__init__(*args, **kwargs)
class ExpandableNameField(forms.CharField): class ExpandableNameField(forms.CharField):
""" """
A field which allows for numeric range expansion A field which allows for numeric range expansion