Skip to content

Instantly share code, notes, and snippets.

@atbradley
Last active April 17, 2020 16:02
Show Gist options
  • Save atbradley/325f1a468d4934b62f6bf3fe88fbbef6 to your computer and use it in GitHub Desktop.
Save atbradley/325f1a468d4934b62f6bf3fe88fbbef6 to your computer and use it in GitHub Desktop.
django-admin command to import model data from an Excel spreadsheet.
#Goes in <your_app>/management/commands
from collections import OrderedDict
from django.core.management.base import BaseCommand, CommandError
from django.apps import apps
from django.db import models
from openpyxl import load_workbook
def workbook_name(filename):
try:
wb = load_workbook(filename)
except:
raise FileNotFoundError("File not found or is not an .xlsx file.")
outp = OrderedDict()
for wsn in wb.sheetnames:
ws = wb[wsn]
header = []
for col in range(ws.max_column):
header.append(ws.cell(1,col+1).value)
outp[wsn] = (header, wb[wsn].iter_rows(min_row=2, values_only=True))
return outp
class Command(BaseCommand):
help="Import data from an Excel worksheet to your application's models"
def add_arguments(self, parser):
parser.add_argument('application')
parser.add_argument('file', type=workbook_name)
def handle(self, *args, **options):
#This will return an error if app 'application' doesn't exist in this project.
apps.get_app_config(options['application'])
for name, wks in options['file'].items():
header, vals = wks
mod = apps.get_model(options['application'], name)
for row in vals:
newthing = mod()
for k, v in zip(header,row):
#Is this field a ForeignKey?
if models.ForeignKey == type(mod._meta.get_field(k)):
cval = mod._meta.get_field(k).foreign_related_fields[0].model.objects.get(id=v)
setattr(newthing, k, cval)
#TODO: Handle e.g. ManyToManyFields
else:
setattr(newthing, k, v)
newthing.save()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment