Search code examples
djangodjango-formsdjango-admin

Override Django Admin Save Model


I want to override Django form save method to be able to create multiple objects at once.

I have an AvailableHours model :

class AvailableHours(models.Model):
    free_date = models.ForeignKey(AvailableDates,null=True, blank=True,on_delete=models.CASCADE,related_name='freedate')
    free_hours_from = models.IntegerField(null=True, blank=True)
    free_hours_to = models.IntegerField(null=True, blank=True,)
    status = models.BooleanField(null=True,default=True,)

and I have a ModelForm for this class :

class TimeGenerator(forms.ModelForm):
    class Meta:
        model = AvailableHours

        fields = ['free_date','free_hours_from','free_hours_to','status']  

    def save(self, commit=True):
        base_item = super().save(commit=False)
        frm = self.cleaned_data['free_hours_from']
        to = self.cleaned_data['free_hours_to']
        items = [
            AvailableHours(
                free_date=base_item.free_date,
                status=base_item.status,
                free_hours_from=hour,
                free_hours_to=hour + 1,
            )
            for hour in range(frm, to)
        ]
        if commit:
            AvailableHours.objects.bulk_create(items)
        return items

I want to create multiple AvailableHours object like this: if the form is set free_hours_from = 13 and free_hours_to=16 so the save method creates 13-14 , 14-15, 15-16 I achieved this by overriding my ModelForm but now I want to override Admin Save model to do this from Django Admin.

I tried by doing it like this in admin.py

class AvailableHoursAdmin(admin.ModelAdmin):
    def save_model(self, commit=True):
        base_item = super().save(commit=False)
        frm = self.cleaned_data['free_hours_from']
        to = self.cleaned_data['free_hours_to']
        items = [
            AvailableHours(
                free_date=base_item.free_date,
                status=base_item.status,
                free_hours_from=hour,
                free_hours_to=hour + 1,
            )
            for hour in range(frm, to)
        ]
        if commit:
            AvailableHours.objects.bulk_create(items)
        return items
admin.site.register(AvailableHours,AvailableHoursAdmin)

but no luck.

anyone has a solution for this ?


Solution

  • Thanks to all answers from contributors below,

    I managed to fix the issues with @Mahammadhusain answer regarding making extra object.

    @admin.register(AvailableHours)
    class AvailableHoursAdmin(admin.ModelAdmin):
        #form = TimeGenerator
        
        def save_model(self, request, obj, form, change):
            super().save_model(request, obj, form, change)
    
            frm = obj.free_hours_from
            to = obj.free_hours_to
            date =obj.free_date
            # Ensure from-to range is valid and create objects within the range
            if frm is not None and to is not None:
                items = [
                    AvailableHours(
                        free_date=obj.free_date,
                        status=obj.status,
                        free_hours_from=hour,
                        free_hours_to=hour + 1,
                    )
                    for hour in range(frm, to)
                ]
                AvailableHours.objects.bulk_create(items)
                
                extra = AvailableHours.objects.get(
                    free_hours_from = frm ,
                    free_hours_to = to ,
                    free_date=date ,
                    )
                extra.delete()