Search code examples
djangodjango-modelsdjango-formsdjango-admindjango-import-export

How to Import from Import-Export(Admin integration) Django with choices?


I have a model:

class Student(models.Model):
TITLE = (
    ('Title_Mr', ('Mr')),
    ('Title_Ms', ('Ms')),
)
Name = models.CharField(max_length = 25, default = '')
Title = models.CharField(max_length = 32, choices = TITLE, blank=True, null = True)
...

with choices and with the Import-Export feature, I want to import students, who have "Mr" or "Ms" as title values.

What I tried was from this answer Django import-export choices field

but apparently this is for exporting? What to do if I want to import it. Here is my resources.py

from import_export import resources, fields

from main.models import Schulungsteilnehmer

class StudentsResource(resources.ModelResource):
    Title = fields.Field(attribute='get_Title_display', column_name=('Title'))
    class Meta:
        model = Student
        exclude=('id',)
        import_id_fields = ('StudentID',)

I can import without problem, but the choicefields are empty, when I click on a student in Admin panel to edit for example. how can I save the values as choice selection values?


Solution

  • Looking at the documentation for choices:

    The first element in each tuple is the actual value to be set on the model, and the second element is the human-readable name.

    So in your case, 'Title_Mr' or 'Title_Ms' is going to be the value stored in the database.

    This means that you would be able to import successfully if you defined your Title field in Resource as follows:

    title = fields.Field(attribute='title', column_name='Title')
    

    (I've made field names lower-case according to style guidelines)

    1. attribute is the attribute on the Model class which is going to be set.

    2. column_name is the name of the header in the import file.

    3. This will only work if the data in the import file matches the choices declaration (e.g. 'Title_Mr')

    However, you said the source data is either 'Mr' or 'Ms'. To solve this, the easiest way would be to make 'Mr' and 'Ms' the values of the choices declaration:

    TITLE = (
        ('Mr', ('Mr')),
        ('Ms', ('Ms')),
    )
    

    But if this is not possible, then you will have to create a custom widget, which can parse the source data (e.g. 'Mr') and translate it to the correct value (e.g. 'Title_Mr').

    For help with creating custom widgets, there are examples in the source.