Skip to main content

django-batch-sheet

Most of the projects we worked on needs a feature to upload data in batch, we always ended up writing another code to handle the Excel sheet and where each column shall go in the model(s), in the latest project we decided to handle it differently and that is why we wrote a django app that handles this like ModelForm handles models and surprisingly, it worked.

Features

  • Generate a Sheet from a Django model or a combination of models (through Combined Sheet),
  • Add the validation rules for Choices, Foreign Keys, Integers automatically in Excel,
  • Showing the required field in red by default
  • Sheet can be validated automatically and check with is_valid()
  • Allow overriding the behavior of model in the class,
  • Allow alot of functions to override the class behavior (row_preprocess,save,pre_load,post_process),
  • Automatic Loading of the data in the sheet to the model.

Install

  1. Install the package
pip install django-batch-sheet
  1. Add it to INSTALLED_APPS
INSTALLED_APPS=[
...
'batch_sheet'
...
]

Example

Let's assume that we have the following models with these rules

  • Patient can have multiple tests but saved once as a Patient Object.
class Test(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name


class Gender (models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

class Patient(models.Model):
    name = models.CharField(max_length=50,verbose_name="Patient Name")
    MRN = models.CharField(max_length=50)
    gender= models.ForeignKey(Gender,on_delete=models.PROTECT,null=True, verbose_name="Gender")
    date_of_birth = models.DateField(null=True,blank=True,verbose_name="Birth Date")
    date_admitted = models.DateField(auto_now_add=True,auto_created=True)
    lastUpdate = models.DateTimeField(auto_now=True)


class RequestedTest(models.Model):
    patient = models.ForeignKey(Patient,on_delete=models.CASCADE)
    test = models.ForeignKey(Test,on_delete=models.PROTECT,verbose_name="Test")
    sample_date = models.DateField(auto_now_add=True,auto_created=True)
    sample_type = models.CharField(max_length=50, verbose_name="Sample Type",choices=(('Blood','Blood'),('DNA','DNA')))
    lastUpdate = models.DateTimeField(auto_now_add=True)

We want to combine both Models in on sheet, so we put the patient information with the requested test in one row.

So For Patient, we will implement the class PatientSheet as follows

class PatientSheet(Sheet):
    def save(self, obj:Patient, row_objs:dict):
        """Lets handle the save manually to check if the MRN exists"""
        patient = Patient.objects.filter(MRN = obj.MRN)
        if patient.exists():
            p = patient[0]
        else:
            p = obj
            p.save()
        return p
    class Meta:
        exclude=('id','date_admitted','lastUpdate')
        Model = Patient
        obj_name = "patient"
        title_header = True

For the Meta attributes, please go to the Meta Attributes sections

For RequestedTest Sheet, it goes like this

class RequestedTestSheet(Sheet):
    def save(self,obj,row_objs):
        patient = row_objs.get('patient')
        if patient is None:
            return None
        else:
            obj.patient = patient
            obj.save()
            return obj

    class Meta:
        exclude =('id','sample_date','lastUpdate')
        validation_exclude = ('patient',)
        title_header = True
        Model = RequestedTest

Now Lets combine them in one sheet

class TestSheet(CombinedSheet):
    patient = PatientSheet()
    test = RequestedTestSheet()

Now Let's Generate The sheet

$ python manage.py generate_sheet --xls App.xls --sheet test_app.sheets.TestSheet

This will the file to App.xls in the folder, now, lets open App.xls

docs/imgs/xls.png

We got the dropdown automatically, based on the value in the database.

Meta Options

    Class Meta:
        rows_count = 10              # Number of rows to apply validations on
        columns = ()                 # Columns to add from the Model to the sheet
        exclude = ()                 # Columns to exclude
        Model = None                 # Model to scan
        raw_cols = []                # Foreign Key Field that shouldn't be set as dropdown
        title_header = False         # Make the titles as "First Name"
        validation_exclude=[]        # Don't validate these field, important in case of objects relationship  
        object_name = None           # The name of the object saved, important in case of Combined Sheet.
            

Release files for django-batch-sheet 0.91.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-batch-sheet 0.91.1
File Size Uploaded
django_batch_sheet-0.91.1.tar.gz 12.2 kB Details

Release files / django_batch_sheet-0.91.1.tar.gz

Download URL django_batch_sheet-0.91.1.tar.gz
Size 12.2 kB
Tags Source
SHA-256 checksum
How to use checksums
f424f0200b0a9d25d85df218bdfd9eacd4d13553563db30f5078a07680a5adf6
BLAKE2b-256 checksum
How to use checksums
8f2547545492d11f43ad7e9e797a68e0536642d99a3fd21542bf7266a9f74f26
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/5.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.91.1 This release

1 release file

0.91.0

1 release file

0.90.0

1 release file

0.20.2

1 release file

0.20.1

1 release file

0.20.0

1 release file

0.10.0

1 release file

0.9.1

1 release file

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page