Загрузка файла в модель, содержащую иностранные ключи

Я успешно создал шаблон, представление и путь, которые позволяют пользователям загружать данные из файла csv непосредственно в модель.

У меня возникли проблемы с моделью, содержащей иностранный ключ. Я ожидал, что это будет проблемой, но уверен, что существует обходной путь.

У меня есть модель VendorItem:

class VendorItem(models.Model):
    sku = models.CharField("SKU", max_length=32, blank=True, null=True)
    vendor = models.ForeignKey(Vendor, on_delete=models.CASCADE, verbose_name="Vendor name", related_name="vendor") 
    vendor_sku = models.CharField("Vendor's SKU", max_length=32)  
    model = models.CharField("Model number", max_length=32, blank=True, null=True)
    description = models.CharField("Description", max_length=64, blank=True, null=True)  
    pq = models.DecimalField('Pack quantity', max_digits=7, decimal_places=2, default=1)                                     
    price = models.DecimalField("Price", max_digits=10, decimal_places=2)  
    upc = models.IntegerField("UPC", blank=True, null=True) # 12-digit numeric barcode
    ian = models.CharField("IAN", max_length=13, blank=True, null=True)    # 13-digit alphanumeric international barcode
    status = models.CharField(max_length=20, choices=STATUS_CHOICES, default=1)
    # Model metadata
    class Meta:
        unique_together = ["sku", "vendor"]
        unique_together = ["sku", "vendor_sku"]
        verbose_name_plural = "Vendor items"
    # Display below in admin 
    def __str__(self): 
       return f"{self.vendor_sku}" 

Поле vendor извлекается из модели Vendor (которая находится в другом приложении, могу добавить):

class Vendor(models.Model):
    number = models.IntegerField("Vendor number", unique=True, blank=True, null=True)
    name = models.CharField("Vendor name", max_length=64, unique=True)   
    region = models.CharField("Vendor region", max_length=64, blank=True, null=True)   
    status = models.CharField(max_length=20, choices=VENDORSTATUS_CHOICES, default=1)      
    # Display below in admin
    def __str__(self):
        return f"{self.name}" 

В 'forms.py', это моя форма загрузки:

class UploadCsvForm(forms.Form):
    file = forms.FileField(validators=[FileExtensionValidator(allowed_extensions=['csv'])])
    # File type validation
    def clean_file(self):
        file = self.cleaned_data.get("file")
        content_type = file.content_type
        # If file type is not csv
        if content_type != 'text/csv':
            raise forms.ValidationError("File type not supported. Please upload a CSV file.")
        return file

В моем 'views.py', вот мой вид:

def upload_items(request):
    submitted = False       # Form is not initially posted
    # If POST request
    if request.method == 'POST':
        # Pass the form
        form = UploadCsvForm(request.POST, request.FILES)
        # If form data is valid
        if form.is_valid():
            # Save the uploaded file to a variable
            file = request.FILES['file']
            # Read the csv file using pandas
            df = pd.read_csv(file)
            # Create a temporary list to store the instances
            items_to_create = []
            # Iterate over each row
            for index, row in df.iterrows():
                sku = row['sku']
                vendor = row['vendor']
                vendor_sku = row['vendor_sku']
                model = row['model']
                description = row['description']
                pq = row['pq']
                price = row['price']
                upc = row['upc']
                ian = row['ian']
                status = row['status']
                # Append this new instance of the model to the temporary list
                items_to_create.append(VendorItem(sku=sku, vendor=vendor, vendor_sku=vendor_sku, model=model, description=description, pq=pq, price=price, upc=upc, ian=ian, status=status))
            # Try to bulk upload all instances to the database
            try:
                VendorItem.objects.bulk_create(items_to_create)
            # For instances that violated field constraints
            except IntegrityError:
                # Loop through the temporary list
                for item in items_to_create:
                    # If the same vendor.number is found in the database, update its fields specified in the defaults brackets below
                    VendorItem.objects.update_or_create(sku=item.sku, defaults={'vendor': item.vendor, 'vendor_sku': item.vendor_sku, 'model': item.model, 'description': item.description, 'pq': item.pq, 'price': item.price, 'upc': item.upc, 'ian': item.ian, 'status': item.status})
            # Redirect to the upload_items page and set submitted=True
            return HttpResponseRedirect('upload_items?submitted=True')
        # If form isn't valid
        else:
            form = UploadCsvForm()
            error_message = 'Invalid file type. Please upload a CSV file.'
            return render(request, 'vendor_items/upload_items.html', {
                'form': form,
                'error_message': error_message
            })
    # If GET request
    else:
        # Initialise the form
        form = UploadCsvForm()
        if 'submitted' in request.GET:
            submitted = True
    # Render the template 
    return render(request, 'vendor_items/upload_items.html', {
        'form': form,
        'submitted': submitted
    })

Наконец, вот мой шаблон:

{% extends 'vendor_items/layout.html' %} <!-- Template inheritance-->

{% block body %}
    <center>
        <h1>Upload vendor items</h1>
        <!-- If upload was successful (POST request)-->
        {% if submitted %}
            The list of vendor items was successfully updated.
        <!-- If file type was incorrect (not csv)-->
        {% elif error_message %}
            <h2>Upload items from a csv file</h2>
            <br>
            <p>{{ error_message }}</p>
            <form action="{% url 'upload-items' %}" method="POST" enctype="multipart/form-data">
                {% csrf_token %}

                {{ form.file }}

                <input type="submit" value="Upload">
            </form>
        <!-- If just arriving at page (GET request)-->
        {% else %}
            <h2>Upload items from a csv file</h2>
            <br><br>
            <form action="{% url 'upload-items' %}" method="POST" enctype="multipart/form-data">
                {% csrf_token %}

                {{ form.file }}

                <input type="submit" value="Upload">
            </form>
        {% endif %}
        <!-- These are always displayed no matter the request-->
        <br>
        <a href="{% url 'vendor-items' %}">Vendor items</a>
        <br><br>
        <a href="{% url 'index' %}">Home</a>
    </center>
{% endblock %}

Мой код правильный, и он действительно хорошо работает, за исключением случаев, когда задействованы иностранные ключи.

Загружаемый мною файл csv содержит поле 'name' модели 'Vendor'. Я хочу, чтобы выгрузка csv выполняла следующее:

1- Чтобы успешно работать, назначая каждый VendorItem существующему Vendor, используя предоставленное имя 'vendor' в csv файле (и таким образом продолжать загрузку VendorItem)

А если вы волшебник Django и будете достаточно добры, чтобы помочь мне на шаг дальше:

2- Для успешной работы путем автоматического создания нового поставщика в модели поставщика только с указанным именем (если поставщика с таким именем еще не существует)

Спасибо за любую предложенную помощь.

Вот ошибка, которую я получаю:

Error message

Поскольку элемент внешнего ключа должен быть целым числом (id), а не строкой, я рекомендую найти внешний ключ (id), который соответствует компоненту имени (строка), до компиляции CSV, а затем заменить строку имени на id внешнего ключа в CSV.

Вернуться на верх