Reputation: 321
I have a model with choices list (models.py
):
class Product(models.Model):
...
UNITS_L = 1
UNITS_SL = 2
UNITS_XL = 3
PRODUCT_SIZE_CHOICES = (
(UNITS_L, _('L')),
(UNITS_SL, _('SL')),
(UNITS_XL), _('XL'),
)
product_size = models.IntegerField(choices=PRODUCT_SIZE_CHOICES)
...
Also I added a new class for exporting needed fields(admin.py
):
from import_export import resources, fields
...
Class ProductReport(resources.ModelResource):
product_size = fields.Field()
class Meta:
model = Product
#I want to do a proper function to render a PRODUCT_SIZE_CHOICES(product_size)
def dehydrate_size_units(self, product):
return '%s' % (product.PRODUCT_SIZE_CHOICES[product_size])
fields = ('product_name', 'product_size')
Class ProductAdmin(ExportMixin, admin.ModelAdmin):
resource_class = ProductReport
But this is not working. How can I get a named value of PRODUCT_SIZE_CHOICES
in export
by Django import-export ?
Upvotes: 5
Views: 4639
Reputation: 1186
In my case I was trying to get the display from a foreign key choice field, like:
user__gender
After unsuccessfully trying the accepted answer and the other answer by Waket, I found this thread here: https://github.com/django-import-export/django-import-export/issues/525
From where I tried a couple of options, and the one that finally worked for me is this:
from import_export.widgets import Widget
class ChoicesWidget(Widget):
"""
Widget that uses choice display values in place of database values
"""
def __init__(self, choices, *args, **kwargs):
"""
Creates a self.choices dict with a key, display value, and value,
db value, e.g. {'Chocolate': 'CHOC'}
"""
self.choices = dict(choices)
self.revert_choices = dict((v, k) for k, v in self.choices.items())
def clean(self, value, row=None, *args, **kwargs):
"""Returns the db value given the display value"""
return self.revert_choices.get(value, value) if value else None
def render(self, value, obj=None):
"""Returns the display value given the db value"""
return self.choices.get(value, '')
user__gender = Field(
widget=ChoicesWidget(settings.GENDER_CHOICES),
attribute='user__gender',
column_name="Gènere",
)
Upvotes: 3
Reputation: 6331
Another solution:
class BaseModelResource(resources.ModelResource):
def export_field(self, field, obj):
field_name = self.get_field_name(field)
func_name = 'get_{}_display'.format(field_name)
if hasattr(obj, func_name):
return getattr(obj, func_name)
return super().export_field(field, obj)
class ProductReportResource(BaseModelResource):
...
Upvotes: 0
Reputation: 1661
You can use 'get_FOO_display' to achieve this in the Django Admin:
class ProductReportResource(resources.ModelResource):
product_size = fields.Field(
attribute='get_product_size_display',
column_name=_(u'Product Size')
)
Upvotes: 21