4

I have a model in which the is an option for setting if an element is active or not.

There is restriction to the number of elements that can have the "active" property with a "True" value.

I have writen validation code on the AdminModel. So now if when editing an elemnt i mark it as "active" and i have reach the limit of "actvie" elements, i raise an exception.

def clean_active(self):
  if self.cleaned_data["active"]:
       #check number of active elements in model.

In the admin interface i have also a list of objects. In this list i have marked as editable the field "active", list_display = ('name', 'first_promotion', 'second_promotion','active') readonly_fields= ['name'] list_editable= ['active']

What I want is to be able of also making this validation on the "list display" of the model. I'm not able where i should add the validation code for the list display.

Could anybody show me how to do this? Thanks in advance.

sandok
  • 53
  • 7

1 Answers1

6

Good question! The changelist form appears to be pulled from ModelAdmin.get_changelist_form where you can supply your own ModelForm to serve as the modelformset base model.

class MyForm(forms.ModelForm):
    def clean_active(self):
        cd = self.cleaned_data.get('active')
        limit = 5 # replace with logic
        if cd >= limit:
            raise forms.ValidationError("Reached limit")
        return cd

    class Meta:
        model = MyModel

class MyModelAdmin(admin.ModelAdmin):
    def get_changelist_form(self, request, **kwargs):
        return MyForm

If you want to modify the formsets validation (the collection of forms) you'd override get_changelist_formset

from django.forms.models import BaseModelFormSet

class BaseFormSet(BaseModelFormSet):
    def clean(self):
        print self.cleaned_data 
        # this is the cleaned data for ALL forms.
        if 'your_condition': 
            raise forms.ValidationError("Your error")

        return self.cleaned_data

class MyModelAdmin(admin.ModelAdmin):
    def get_changelist_formset(self, request, **kwargs):
        kwargs['formset'] = BaseFormSet
        return super(MyModelAdmin, self).get_changelist_formset(request, **kwargs)
Yuji 'Tomita' Tomita
  • 115,817
  • 29
  • 282
  • 245
  • Thanks a lot. That a really fast answer and it works. I have used the same "modelform" i was using in the single object admin and it seems to work. Now i'm having an error in every field which is active (onece i have passed the limit). I suppouse i can tweek this so i only display an error en the rows i have just edited – sandok Jan 22 '12 at 21:01
  • and do you know how can I check during the validation of "active" if the value "true" or "false" is the same or changed from the saved value? – sandok Jan 22 '12 at 21:10
  • I might just compare vs the database... `if self.instance.id: changed = self.model.objects.get(id=self.instance.id).active != self.cleaned_data.get('active')` because IIRC modelforms don't do a GET they just start populating values directly from the posted data... – Yuji 'Tomita' Tomita Jan 22 '12 at 21:17
  • that looks like a problem :) .Every thing works fine until you set in one submit let seid ...3 more than the limit. IN that case, the form does not complaint about it...Is it posible to keep a counter inside the "clean_active"? – sandok Jan 22 '12 at 22:08
  • Hm? That's odd - if any form is invalid in a formset, the whole formset is invalid. You'll need to come up with your specific logic. I'm not sure how your limit is determined. – Yuji 'Tomita' Tomita Jan 22 '12 at 22:19
  • lets say the limit is 23. :). I think "clean_Active" it's not the place for this. Sure this can be written in other place ...i'm quite new to django...Maybe the is somewhere of trigering a "full model validation" when working with list forms ?¿... – sandok Jan 22 '12 at 22:34
  • You're going to have to clarify what you need then - we can only give you general advice about your problems. If it's not a **per model** validation, then you may be looking to override the `formset` used in the changelist view - adding an update. – Yuji 'Tomita' Tomita Jan 22 '12 at 22:47