Tom Myers Tom Myers -4 years ago 116
Python Question

Foreign Key Not Setting On CSV Upload -- Django

When importing csv to django the foreign keys are not setting. May code may be wrong. I am able to import the foreign keys but I am not able set them in the product object.

I do not want to have to back through and set the foreignkeys manually.

models

from django.db import models
from django.core.urlresolvers import reverse
from django.template.defaultfilters import slugify

# Create your models here.
class Category(models.Model):
parent = models.ForeignKey('self', blank=True, null=True)
category_name = models.CharField(max_length=250, blank=True)
slug = models.SlugField(max_length=250, unique=True)

def save(self, *args, **kwargs):
self.slug = slugify(self.category_name)
super(Category, self).save(*args, **kwargs)

#def get_absolute_url(self):
#return reverse('products:category', args=[self.id]) #kwargs={'slug': self.slug}

def __str__(self):
return self.category_name

class Company(models.Model):
company_name = models.CharField(max_length=500)
company_url = models.URLField(max_length=1000, blank=True)
slug = models.SlugField(max_length=500)

def save(self, *args, **kwargs):
self.slug = slugify(self.company_name)
super(Company, self).save(*args, **kwargs)

#def get_absolute_url(self):
#return reverse('products:category', args=[self.id]) #kwargs={'slug': self.slug}

def __str__(self):
return self.company_name

class Manufacturer(models.Model):
manufacturer_name = models.CharField(max_length=500)
slug = models.SlugField(max_length=500)

def save(self, *args, **kwargs):
self.slug = slugify(self.manufacturer_name)
super(Manufacturer, self).save(*args, **kwargs)

#def get_absolute_url(self):
#return reverse('products:category', args=[self.id]) #kwargs={'slug': self.slug}

def __str__(self):
return self.manufacturer_name

class Product(models.Model):
product_name = models.CharField(max_length=500, blank=True)
product_description = models.TextField(blank=True)
company = models.ForeignKey(Company, blank=True, null=True)
category = models.ForeignKey(Category, blank=True, null=True)
manufacturer = models.ForeignKey(Manufacturer)
buy_link = models.URLField(max_length=1000, blank=True)
product_image_url = models.URLField(max_length=1000, blank=True)
price = models.CharField(max_length=30, blank=True)
orginal_price = models.CharField(max_length=30, blank=True)
stock = models.CharField(max_length=30, blank=True)
sku = models.CharField(max_length=250, blank=True)
slug = models.SlugField(max_length=500, unique=True)
date_added = models.DateTimeField(auto_now_add=True, auto_now=False)
updated = models.DateTimeField(auto_now_add=False, auto_now=True)

def save(self, *args, **kwargs):
self.slug = slugify("{obj.product_name}-{obj.id}".format(obj=self))
super(Product, self).save(*args, **kwargs)

def get_absolute_url(self):
return reverse('products:product_detail', args=[self.slug]) #kwargs={'slug': self.slug}

def __str__(self):
return self.product_name


views

def upload(request):
if not request.user.is_authenticated:
return redirect("home")

csv_path = os.path.dirname(os.path.abspath(__file__))
try:
with open(csv_path + '/product.csv') as f:
reader = csv.reader(f)
for row in reader:
_, created = Product.objects.get_or_create(
product_name=str(row[0]),
buy_link=str(row[2]),
product_image_url=str(row[3]),
price=str(row[4]),
orginal_price=str(row[5]),
product_description=str(row[6]),
stock=str(row[7]),
sku=str(row[10]),
)
_, created = Company.objects.get_or_create(
company_name=str(row[1]),
)

_, created = Manufacturer.objects.get_or_create(
manufacturer_name=str(row[8]),
)

_, created = Category.objects.get_or_create(
category_name=str(row[9]),
)
success = "Added to database"
context = {"success": success}

except csv.Error as e:
print(e)
context = {'error': e}

template = "products/add.html"

return render(request, template, context)

Answer Source

Below is an example of what I was thinking you'd need to do:

def upload(request):
    if not request.user.is_authenticated:
        return redirect("home")

    csv_path = os.path.dirname(os.path.abspath(__file__))
    try:
        with open(csv_path + '/product.csv') as f:
            reader = csv.reader(f)
            for row in reader:
                category_obj, created = Category.objects.get_or_create(
                    category_name=str(row[9]),
                )

                company_obj, created = Company.objects.get_or_create(
                    company_name=str(row[1]),
                )

                manufacturer_obj, created = Manufacturer.objects.get_or_create(
                    manufacturer_name=str(row[8]),
                )

                product_obj, created = Product.objects.get_or_create(
                    product_name=str(row[0]),
                    company=company_obj,
                    category=category_obj,
                    manufacturer=manufacturer_obj,
                    buy_link=str(row[2]),
                    product_image_url=str(row[3]),
                    price=str(row[4]),
                    orginal_price=str(row[5]),
                    product_description=str(row[6]),
                    stock=str(row[7]),
                    sku=str(row[10]),
                )

        success = "Added to database"
        context = {"success": success}

    except csv.Error as e:
        print(e)
        context = {'error': e}

    template = "products/add.html"

    return render(request, template, context)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download