我可以通过多对一关系映射将CSV批量上传到Django吗?

时间:2016-07-01 17:26:29

标签: python django csv mapping

我正在尝试查找/创建一个允许将数据批量上传到Django的模块。我试图将许多艺术家与一个特定的节日联系在一起,但到目前为止我发现的所有模块只支持1:1上传。 https://github.com/edcrewe/django-csvimport

1 个答案:

答案 0 :(得分:2)

这是您想要做的一个例子。我已经删除了原始代码,因为它太大了。但这仍然会给你一个很好的起点。

实际上,客户端上传的CSV文件并不像我在示例中所示的那样简单。有些行是空白的,有些行包含一些其他不必要的信息,比如生成文件的软件名称,商店名称等等。所以我不得不写一些方法来过滤掉那些数据。但我还没有在下面做过。我尽可能地保持这个例子的最小化。

from django.db import models
import csv


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


class Product(models.Model):
    category = models.ForeignKey(Category)
    uid = models.CharField(max_length=4)
    name = models.CharField(max_length=10)
    price = models.IntegerField()
    qty = models.IntegerField() # quantity


class CSVFile(models.Model):
    """
    This model allows for uploading a CSV file and then 
    updates data in Category and Product models
    """
    csv_file = models.FileField(upload_to='csvfiles')
    # feel free to add other fields like upload date, etc.

    def save(self, *args, **kwargs):
        """
        This is where you analyze the CSV file and update 
        Category and Product models' data
        """
        super(CSVFile, self).save(*args, **kwargs)
        self.csv_file.open(mode='rb')
        f = csv.reader(self.csv_file)
        for row in f:
            # currently the row is a list of all fields in CSV file
            # change it to a dict for ease
            row_dict = self.row_to_dict(row) # this method is defined below
            # check if product exists in db
            product = self.product_is_in_db(row_dict['uid']) # this method is defined below
            if product:
                # product is in db
                # update fields values
                self.update_product(product, row_dict) # this method is defined below
            else:
                # product is not in db
                # create this product
                self.create_product(row_dict) # this method is defined below

        self.csv_file.close()


    def row_to_dict(self, row):
        """Returns the given row in a dict format"""
        # Here's how the row list looks like:
        # ['category', 'product name', 'product uid' 'price', 'qty']
        return {'category': row[0], 'name': row[1], 
            'uid': row[2], 'price': row[3], 'qty': row[4]
            }

    def product_is_in_db(self, uid):
        """Check the product is in db. 
        If yes, return the product, else return None
        """
        try:
            return Product.objects.get(uid=uid)
        except Product.DoesNotExist:
            return None

    def update_product(self, product, row_dict):
        """Update the given product with new data in row_dict"""
        product.price = row_dict['price']
        product.qty = row_dict['qty']
        product.save()

    def create_product(self, row_dict):
        # First see, if category exists
        # If not, create a new category
        try:
            category = Category.objects.get(row_dict['category'])
        except Category.DoesNotExist:
            category = Category.objects.create(name=row_dict['category'])

        # Now, create the product
        Product.objects.create(
            name=row_dict['name'],
            uid=row_dict['uid'],
            price=row_dict['price'],
            qty=row_dict['qty'],
            category=category,
        )