Skip to content

One Object per User in a Model

Posted in Django

Sometimes, just sometimes, we want our users to add only one object per user per model. As in, when they add an object to a model, the can only add another object, ONLY after their first object is deleted.

Let’s jump right into some code. Let’s use this model as an example:

At any point in time, I want to ensure a user only has only a single Package object in the model.

Check my article about Extending the Django User Model like a Pro.

A Possible Approach

Here’s the logic behind the approach above:

  • A context is passed on to the template, with a True or False value.
    • This value is determined via checking to see if the currently logged in user has an item within the Package model and returning a Boolean

This context variable can, therefore, be checked in the template and used in rendering the template for sending to the client.

So, in the template, we can trap and make a decision with the context data in a way like this:

If you’re wondering what all that yesno magic was about, well, you can think of it as same as:

except the yesno built-in Django tag is just too clean to not use! However, it ain’t a magic bullet for all if/else scenarios, since it is designed for strings.

“Maps values for True, False, and (optionally) None, to the strings “yes”, “no”, “maybe”, or a custom mapping passed as a comma-separated list, and returns one of those strings according to the value”

Downsides to Approach

  • Of course, this approach does the checking template-side only. If however done, a user manages to send in a valid form to the server, it will save.
    • How that will happen is something I’m keen to learn.
  • There isn’t any extra check at the model level. If you’re sending the form via an API and bypassing the views.py somehow, users can save as many objects as they want.
  • Too tedious to do for multiple models. If a single-case model, the above approach might be a quick fix. However, if you want one object per user per model for 20 models, I doubt the above strategy is worth it. You might have to look into Django packages able to apply model level user restrictions.

Conclusion

I hope you found this straightforward approach useful. I hope to catch you in the next one.