Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Another solution might be to use django signals.</p> <p>Django will send a <code>pre_save</code> signal before saving any model, so you can hook a function to react to it and perform your checks.</p> <p>something along the lines of (building off @Eliot Berriot solution):</p> <pre><code>from django.db.models.signals import pre_save from django.core.exceptions import ValidationError def validate_num_books(sender, **kwargs): if isinstance(sender, Student): max_books = 3 elif isinstance(sender, Employee): max_books = 30 books_count = sender.books.all().count() if books_count &gt;= max_books: raise ValidationError("This person has too much books !") pre_save.connect(validate_num_books, sender=Employee, dispatch_uid='validate_num_books') pre_save.connect(validate_num_books, sender=Student, dispatch_uid='validate_num_books') </code></pre> <p>Notes:</p> <ol> <li><p>I'm not sure the ValidationError will have the intended effect. Hopefully it'll be enough to bypass the model being saved, but maybe it doesn't work quite that way, or it does in some situations or but not in others... Consider this snippet as experimental pseudo code.</p></li> <li><p>As you might have guessed from the point above, i'm not that used to signals, and still a bit weary of those. This might be completely fine, but if a cleaner solution arises, i'd probably go for it and avoid signals entirely. Simpler is usually better.</p></li> <li><p>The only advantage i can see of this solution over Eliot's answer is that it avoids inheritance, which, as he said, can cause performance trouble. However, if you avoid defining fields on the parent class, I <em>think</em> you should be fine.</p></li> </ol> <p>If you decide to experiment with signals, <a href="https://docs.djangoproject.com/en/dev/topics/signals/" rel="nofollow">start here</a>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload