Ansel Zandegran
Ansel Zandegran

Reputation: 656

django: limiting model instance based on foregin key

I have a models like these

class Campaign(models.Model):
   campaign_name= models.CharField(max_length=30)
   user=models.ForeignKey(User)
   rows=models.IntegerField(default=3)
   columns=models.IntegerField(default=1)
   def __str__(self):                 # __unicode__ on Python 2
       return self.campaign_name+": "+self.campaign_desc

   def save(self, *args, **kwargs):
       print("Doing Custom Task ")
       super(Campaign, self).save(*args, **kwargs) # Call the "real" save() method.

class Item(models.Model):
   campaign=models.ForeignKey(Campaign)
   item_name=models.CharField(max_length=70)
   item_ID=models.CharField(max_length=400)
   def __str__(self):
       return self.item_name

I have registered Campaign in admin using admin.site.register(Campaign,CampaignAdmin) and want the number of items in each campaign to be rows X columns of campaign (Foreign key).

Q1) If I validate it using the save override method in the place of print("Doing Custom Task ") , I couldn't save the instance when it's created.

Q2) It would be also nice to have the number of items to be filled to show up appropriately. Now I have

class ItemInline(admin.TabularInline):
   model = Item
   #extra = 4

in admin.py Basically I want the extra parameter to be rows X columns

Upvotes: 0

Views: 51

Answers (1)

Alex Morozov
Alex Morozov

Reputation: 5993

  1. If you want to do some custom validation, you'd better do it via forms, or (as a last resort), using the Model.clean* methods family.

    class Campaign(models.Model):
        def clean(self):
            if self.pk:
                if self.item_set.count() > 5 # Or whatever number you need
                    raise ValidationError(_('Too much items for me.'))
    
  2. Override the get_extra() method for your inline:

    class ItemInline(admin.TabularInline):  
        extra = 4
        def get_extra(self, request, obj=None, **kwargs):           
            if obj:
                return obj.rows * obj.columns
            return self.extra
    

Upvotes: 1

Related Questions