title: limit number of foreign key using Django CheckConstraint
body: <p>I am using Django 4.1 and Postgresql and as stated in their documentation <code>CheckConstraint </code> accept <code>Q</code> object and <code>Expression</code>.</p>
  <p>Based on <a href="https://code.djangoproject.com/ticket/31646" rel="nofollow noreferrer">https://code.djangoproject.com/ticket/31646</a>, I thought my solution would work, but when calling <code>makemigrations</code> nothing happens (<code>Count</code> inherit from <code>Func</code>).</p>
  <p><strong>Goal:</strong> I would like to limit the number of Messages per Discussion.</p>
  <p>I did see a solution using a validators on the ForeignKey field but it is not robust (see  <a href="https://stackoverflow.com/questions/24586223/limit-number-of-foreign-keys">Limit number of foreign keys</a>). I would prefer not to have to create a SQL function and calling it (would like a Django solution only).</p>
  <pre class="lang-py prettyprint-override"><code>from django.core.exceptions import ValidationError
  from django.db import models
  from django.db.models.lookups import IntegerLessThan
  
  class Discussion(models.Model):
      MAX_MESSAGES = 10
  
  
  class Message(models.Model):
      discussion = models.ForeignKey(
          &quot;discussion.Discussion&quot;,
          models.CASCADE,
          related_name=&quot;messages&quot;,
      )
      constraints = [
          models.CheckConstraint(
              name=&quot;limit_discussion_messages&quot;,
              check=IntegerLessThan(
                  models.Count(&quot;discussion&quot;, filter=models.Q(discussion=models.F(&quot;discussion&quot;))),
                  models.Value(Discussion.MAX_MESSAGES),
              ),
          ),
      ]
  </code></pre>
  <p><strong>EDIT:</strong>
  After some discussion in the comments and reading provided anwser here are my findings:
  Perfect constraint (without data race) cannot be achieved with Django and no raw SQL in it's current state (4.1).</p>
  <p>Using a Django solution only and it's validators system, you have two choices:</p>
  <ul>
  <li>Check before saving and accept the fact that you might have a few more records than the allowed limit</li>
  <li>Check after saving and accept the fact that you might rollback more operation than necessary, but allowed limit will be enforced</li>
  </ul>