Как заполнить поле ManyToMany в Django, используя файл .csv? - PullRequest
0 голосов
/ 26 июня 2019

У меня есть 2 модели Influencer и Категория. Influencer имеет много-много отношений с категорией. Модели выглядят так:

class Category(models.Model):
    name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

и

class Influencer(models.Model):
    full_name = models.CharField('Full Name',max_length=100)
    username = models.CharField('Username',max_length=100,unique=True)
    photo = models.ImageField(upload_to = 'photos/%Y/%m/%d/',blank=True)
    location_city = models.CharField('Location City',max_length=100,null=True,blank=True)
        categories = models.ManyToManyField(Category)

Я написал скрипт на python, который анализирует CSV-файл и отправляет данные в базу данных PostgreSQL.

В CSV-файле столбец Category представлен в виде массива, как показано ниже

['Food', 'Bar', 'Bar', 'Student', 'Student', 'makeup', 'makeup', 'India', 'India']

Скриншот файла CSV enter image description here

Когда я печатаю тип столбца Category в python, он показывает его в виде строки. Функция, которую я написал для анализа и отправки данных в базу данных, выглядит следующим образом. На данный момент я исключил опцию категорий из функции.

def write_to_db(file):
    with open(str(file),encoding='utf-8') as csvfile:
            csvreader = csv.reader(csvfile)
            next(csvreader,None)
            for row in csvreader:

                try:
                    if not Influencer.objects.filter(username = row[1]).exists() and check_email(row[2]):
                        _,created = Influencer.objects.get_or_create(
                                full_name = row[0],
                                username = row[1],
                                email_id = clean_email(row[2]),
                                external_url = row[8],


                                )

                except Exception as e:
                    print(e)

Как мне написать код, чтобы я мог вставить категории в поле «многие ко многим» с соответствующим Первичным ключом влияния.

Есть ли другие альтернативы, кроме использования ManyToManyField? Я пробовал django-multiselected поле, но оно не работает хорошо.

1 Ответ

1 голос
/ 26 июня 2019

Это должно сработать:

import ast

def write_to_db(file):
    with open(str(file),encoding='utf-8') as csvfile:
        csvreader = csv.reader(csvfile)
        next(csvreader,None)
        for row in csvreader:
            try:
                if not check_email(row[2]):
                    continue
                influencer, _ = Influencer.objects.get_or_create(
                    full_name = row[0],
                    username = row[1],
                    email_id = clean_email(row[2]),
                    external_url = row[8],
                )
                categories_str = row[5]
                category_names = ast.literal_eval(categories_str)
                category_names = map(str.lower, category_names) # normalize them, all lowercase
                category_names = list(set(category_names)) # remove duplicates
                for category_name in category_names:
                    category, _ = Category.objects.get_or_create(name=category_name)
                    influencer.categories.add(category)
            except Exception as e:
                print(e)

Я предполагаю, что формат, который я вижу там в столбце категорий, соответствует вставленному вами фрагменту (используя одинарные кавычки и [] для обозначения списка). В этом случае модуль ast можно использовать для синтаксического анализа этого столбца непосредственно в литерал Python, список строк;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...