Multiple parent child objeects on a single page

Continuing the discussion from Welcome to Using Django:

Hi all,

Ive ben using Django for quite a while and built some sites already. (www.peugeotclubmalaysia.com). I am working on a site that seems quite simple but am having trouble wrapping my head around the details of the implementation of a single form to capture multiple parent child relationships.
Concept is a dynamic checklist where users can create a category and a list of items related to the category.

model.py

class InspectionCategory(models.Model):

    category = models.CharField("Category", max_length=200)
    sequence = models.IntegerField("Sequence")
    

    class Meta:
        verbose_name = "Category"
        verbose_name_plural = "Categories"
        ordering = ['sequence',]

    def __str__(self):
        return self.category

    def get_absolute_url(self):
        return reverse("category_detail", kwargs={"pk": self.pk})  

    def get_submit_status(self):
    	return "testtest"    
 
class ItemInCategory(models.Model):
    FIELDTYPE = ( ('checkbox','CheckBox'),
    ('text','Textfield'),('number','NumberField'),('date','DateField'))
    ERRORTYPE = [ ('NONE','None'),('STATUTORY','Statutory'),
    ('SAFETY','Safety'),('ENGINEERING','Engineering'),('OPERATIONS','Operations'),('POWER','Power')]

    category = models.ForeignKey("InspectionCategory", verbose_name="Category", on_delete=models.CASCADE, related_name='items', default=3)
    items = models.CharField("Item", max_length=200)
    show_in_section=models.IntegerField("Show in Section",default=0)
    throw_error = models.BooleanField("Throw error if True")
    sequence = models.IntegerField("Sequence")
    fieldtype = models.CharField(max_length=20, choices=FIELDTYPE) 
    errortype = models.CharField(max_length=20, choices=ERRORTYPE, default=' ', verbose_name="Category")
    severity = models.IntegerField("Risk Factors",default=0)
    
    
    class Meta:
        verbose_name = "Item"
        verbose_name_plural = "Items"
        ordering = ['sequence',]

    def __str__(self):
        return self.items

Challenge 1
I have currently managed to develop this using function based views and javascript / ajax but i find it so frustrating that i couldn’t figure out how to use CBV to display and the save the results of multiple Category and Items in a single page. Current implementation has a javascript that saves each section but i actually require a final save after every cate/item has been completed.

Currently data is being saved into this model. (one model for the base display and the below to store the selected/ filled data)

class InspectionMaster(models.Model):
    site_id = models.ForeignKey("Sites",  on_delete=models.CASCADE)
    user_id = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    add_date = models.DateField("Add Date", auto_now_add=True)
    update_date = models.DateField("Update Date",  auto_now_add=True)

    class Meta:
        verbose_name = "Inspection Result"
        verbose_name_plural = "Inspections Result"

    def __str__(self):
        return str(self.id)


class InspectionDetails(models.Model):
    master_id = models.ForeignKey("InspectionMaster", verbose_name="InspectionMaster", on_delete=models.CASCADE, related_name='details', default=3)
    category_id = models.ForeignKey("InspectionCategory",  on_delete=models.CASCADE)
    item_id = models.ForeignKey("ItemInCategory",  on_delete=models.CASCADE) #models.CharField("Item Id", max_length = 200)
    item_value = models.CharField("Item value", max_length = 500)
    item_image= models.ImageField(upload_to=None, height_field=None, width_field=None, max_length=100)

    class Meta:
        verbose_name = "Detail"
        verbose_name_plural = "Details"

    def __str__(self):
        return self.item_value

HELP NEEDED: how would i setup my forms.py and use it as a CBV to get/put data for the entire set of parent/child data.

Challenge 2
Not everything requires to be filled so maybe only one checkbox will be ticked at a time and that needs to be saved. (and retrieved later). Again its been done but using FBV and not CBV.
HELP NEEDED: how would i use the CBV to display the previous results when im viewing the data.


Site is a WIP and can be viewed at inspection.grafnet.work/inspect (user:mark / pass:asdfgh!23)

Would be really grateful if can clean up and do this in a Django-like way with CBV / forms etc. rather that alot of workarounds with javascript etc.

What I think you want to start looking at are the Formsets
It’s a way of supplying multiply copies of the same form on a page, and with a little JavaScript mixed in, can be used to add / delete elements from that grid.

I thought of using Formset but in my scenario. I will be using the initial model Category and IteminCategory to display the layout of the fields i want to capture date for.
When i perform a save i will be saving the filled / selected fields to the InspectionMaster and InspectionDetails tables. A Formset uses the fields referenced to display the initial fields so not sure how i would be then saving the data to antoher model. Unless im missing something to get this to work. Would be great if you could just go to the site and test it out. It currently works now but im not using the CBV to get it to work lots of ugly javascript which i hope to reduce or avoid.