1
votes

I'm using a django-import-export Django library, but it's not working for m2m relationships.

I have the following models.py:

class Writer(models.Model):
    name = models.CharField(verbose_name='Nome', max_length=20)
    last_name = models.CharField(verbose_name='Sobrenome', max_length=50, default='')

    def __str__(self):
        return '%s (%s)' % (self.last_name,self.name)


class Book(models.Model):

    book = models.CharField(verbose_name='Título', max_length=200)
    isbn = models.CharField(verbose_name='ISBN:',max_length=13,help_text='13 Caracteres')
    writer = models.ManyToManyField('Writer', verbose_name='Escritor(es)')

    def __str__(self):
        return self.book

    # Cria uma string a partir dos 3 primeiros nomes de autores (se existe)
    def display_writer(self):
        """
        Creates a string for the Genre. This is required to display genre in Admin.
        """
        return ', '.join([ writer.name for writer in self.writer.all()[:3] ])
    display_writer.short_description = 'Writer'

O arquivo de resources.py:

from import_export import resources
from import_export.fields import Field
from import_export.widgets import ManyToManyWidget
from .models import Book, Writer

class BookResource(resources.ModelResource):

    writer = Field(column_name='writer', attribute='writer', widget=ManyToManyWidget(Writer,separator=',', field='name'))

    class Meta:
        model = Book
        skip_unchanged = True 
        report_skipped = False
        import_id_fields = ( 'isbn' ,) 
        fields = ('isbn', 'book', 'writer', )

When importing a csv file, it does not give errors, but it does not matter the data of the m2m field.

Follows examples of the data in the csv file.

enter image description here

1
What does the csv data look like?Håken Lid
The reason might be because you are setting skip_unchanged to true. Could you try by changing the data or by setting the flag to false.Sagar Ramachandrappa
@HåkenLid, include up the csv data image.Anne Kelly
@Sagar I did the test configuring it as false but continued importing without the data from the field "writer".Anne Kelly
Did you ever get this to work?Andy Poquette

1 Answers

0
votes

The issue is skip_unchanged = True. This may seem unintuitive, but it should read skip_unchanged = False.

To understand the reason for this you need to consider the data that Django is maintaining. skip_unchanged says to skip the row import when no changes are being made to the model table. When you change a M2M relationship the model table doesn't change. Instead the relationship table changes.

In your case you will have the following tables in the Django database:

  • <app>_writer - All the authors.
  • <app>_book - All the books.
  • <app>_book_writer - The many-to-many relationships that link books with their writers.

When you import an existing book and only change the writer the only table that will be updated is <app>_book_writer. For some reason the import/export plugin doesn't consider this a change to the book model, so skips it.