Creating points subsets in django-models
<p>I am looking for a scalable way to create new user points subsets without migrating each time a new subset is created.</p>

<p>For example, say I have a <code>users</code> app with a model where <code>total_points</code> is the sum of <code>pts_1</code>, <code>pts_2</code>, and <code>pts_3</code> for each user.</p>

<p>I have also created a <code>campaigns</code> app that enables users to earn points by performing an action (say, clicking a button for simplicity). I can add new campaigns to the platform through the Django admin and set it up so that when users complete the campaigns, they are credited with points such that <code>(campaign, pk=n)</code> credits that user's <code>pts_n</code>.</p>

<p>However, in order to do this, I need to manually add <code>pts_n</code> to <code>models.py</code> and migrate to the database. Is there a better solution? The only thing that I can think of is pre-populating <code>pts_n</code> in batches to avoid migrating every time I add a new campaign.</p>

<p>Am I thinking about this the wrong way? I am pretty new to this.</p>

<p>The easiest solution would be to create a UserPoints model where you record the awarding of points.</p>

<pre><code>class UserPoints(models.Model):
    user = models.ForeignKey('auth.User', on_delete=models.CASCADE)
    date = models.DateTimeField(auto_now_add=True)
    points_amount = models.IntegerField(default=1)
    points_category = models.CharField(max_length=50, blank=True, null=True)
</code></pre>

<p>This model assumes that the category is optional.</p>

<p>Now you can dynamically calculate a user's points:</p>

<pre><code>user = request.user
UserPoints.objects.filter(user=user).aggregate(Sum('points_amount'))
</code></pre>

<p>If you want just the amount of points from a certain category:</p>

<pre><code>category = 'my_category'    
UserPoints.objects.filter(user=user, category=category).aggregate(Sum('points_amount'))
</code></pre>

<p>Your solution where you would constantly be adding <code>pts_n</code> columns to the database is clearly not preferable here, since that would be a lot of work and you would be using the <code>total_points</code> column as an aggregate of other columns which is not a recommended practice.</p>

python django django-models architecture scalability