Search code examples
pythondjangodjango-modelsdjango-modeladmin

How to access Django Model Fields from save_formset


I have an Inline Model in Django model admin , and I need to create a condition before saving the items, here is the code am using :

class PRCItemInline(admin.TabularInline):


    def get_form(self, request, obj=None, **kwargs):
        form = super(PRCItemInline, self).get_form(request, obj, **kwargs)
        form.base_fields['product'].widget.attrs['style'] = 'width: 50px;'
        return form

    ordering = ['id']
    model = PRCItem
    extra = 1
    autocomplete_fields = [
        'product',
        'supplier',
    ]

    fields = (
        'product',  # 1
        'quantity',  # 2
        'unitary_value_reais_updated',  # 4
        'issuing_status',
        'approval_status',
        'receiving_status',
    )
    readonly_fields = ['issuing_status',
                       'approval_status',
                       'receiving_status',
                       ]

    def save_formset(self, request, form, formset, change):
        obj = form.instance
        if obj.purchase_request.is_analizer:
            return HttpResponse("You can't change this")
        else:
            obj.save()

As you see, I used the save_formset method to be able to reach the fields of the model, and then filter based on it. but it just saves the items no matter the If statement I added.


Solution

  • First thing:

    List item save_formset should not return anything, the HttpResponse will not work for you. Even if it would this is just not proper way. Not mentioning that it will not be very informational.

    1st solution

    obj.purchase_request.is_analizer should be done during form validation

    Any ValidationError raised there will be propagated to the formset and displayed in error message next to relevant form.

    class PRCItemForm(forms.ModelForm):
        def validate(self):
            if obj.purchase_request.is_analizer:
                raise ValidationError("You can't change this")

    2nd solution

    override get_queryset() and filter out the objects you cannot edit

    def get_queryset(self):
        qs = super().get_queryset()
        return qs.exclude(purchase_request__is_analizer=True)