Django - Import CSV to model, handling relationships to other models

Viewed 105

Let's suppose we have Author and Book models:

class Author(models.Model):
    first_name = models.CharField(max_length=60)
    last_name = models.CharField(max_length=60)

    def __str__(self):
        return self.last_name

class Book(models.Model):
    title = models.CharField(max_length=60)
    author = models.ForeignKey(Author, on_delete=models.CASCADE)

    def __str__(self):
        return self.title

And we try to do multiple inserts using CSV files:

(author.csv)

FirstNameA, LastNameA
FirstNameB, LastNameB 

(book.csv)

FirstTitle, LastNameA
AnotherTitle, LastNameA
OneMoreTitle, LastNameB 

I try to build a class-based view which imports a CSV in a model.

The view:

  • is given the name of the model as an argument
  • fetches the model and its fields and uses get_or_create method in a loop for each row of the CSV.

.

class ImportCSV(View):

    ...

    def post(self, request, model_name):
        model = apps.get_model('app', model_name)
        fields = list(modelform_factory(model=model, fields='__all__').base_fields.keys())
        
        file = request.FILES['csv_file']
        decoded_file = file.read().decode('utf-8').splitlines()
        reader = csv.reader(decoded_file)
        for row in reader:
            dict = {}
            for i, field in enumerate(fields):
                dict[field] = row[i]

            _, created = model.objects.get_or_create(**dict)

While it works for Author model, it does not work for Book model, due to ForeignKey field. It expects an id (number), not the value that __str__ returns for this record. It is totally logical. The question is, how can I handle such an import? What I would like to tell Django to do is:

If it is a foreign key, find the id of the book that is associated with this string (last name).

PS: I know that ID and Last Name may not be a 1-to-1 relationship, I just leave it as is for this example

0 Answers
Related