Restrict Number of Form Submission in Django
Django is a great Python based web framework, which comes with tons of features out of the box, for ‘springboarded’ development. Django rides on Python, thus, the whole Python packages ecosystem is available to every developer’s disposal. Sweet!
At certain junctures in the development flow using Django, its very common to find yourself scratching your head, and asking, ‘Why isn’t this feature baked in? Why doesn’t this work that way?’. Well, I’ve come across such questions every now and then, and although I don’t expect every possible scenario to be included in a framework (which would ridiculously insane), some basic ones would do.
For instance, why is there an add filter in Django’s template, but there’s no subtract, or multiply? In situations of that sort, you’ll need to implement your own solution. Implement your own solution you must do, because as you could realize from the above link thread, irrespective of how simple (maybe just 3 lines of code) a solution can be, the core developers aren’t going to nod to all what you say at first-hearing.
What exactly is/was my problem?
Django, out of the box, has a field on the User model, called the last_login. This last_login field, as the name suggests, stores the date timestamp of whenever a user logs in. This is a very handy Boolean field, which can do wonders if you need it, and you can find other effective uses of it.
My problem was/is this:
- I have a form
- I want a logged in user to be able to submit
- Yes, submit, but ONLY once a day. So after submitting the form successfully, the form doesn’t even render anymore in the template. (Front end could be used to accomplish this form-hiding thing by each user, but I want(ed) a server side restriction
- That’s it
How I solved it?
I don’t think my solution is the best out there, but for the mean time, it works, and has no issues. The moving parts, doesn’t look that few in number, but they’ve been greased well, thus less friction. Reusability? I doubt it is, but hey, until I figure out a better way, that’s how it is for now.
The solution goes like this:
- Two forms are created. One is the actual form visible to the user when submitting (Normal Form) and the second is the form responsible for triggering another form that the user has submitted a form (Control Form)
- Both forms are rendered in template. Control Form is hidden. Values for the CF is prepopulated at the form.instance.* level in my views, thus, no errors are thrown in the template.
- Both forms are submitted once, within one submit button.
- Upon rendering the form again, views check if Control Form has been populated by the request.user. If so, then form is hidden. If not, form shows
- I want users to have opportunity to submit form ONLY once a day, thus, what I do is just wipe the Control Form database at midnight, everyday
- That’s it
Can I see some code? Yes!
Now, the above is my solution. I’ve tried to comment as much as possible, and I’ll be updating it with changes I make. My current solution is live in production at logECG, and its working as expected.
However, I believe there might be a better way to handle such a problem in a proper way. Have you encountered similar issue in your line of work? How did you solve it? I’ll love to learn of ideas of how to improve this.
So the initial rant about Django, What for?
Just like the last_login field on the User model, perhaps a feature could be available regarding forms, in which, a signal is triggered and stored, per count, how many times a user in context submits or does something relating to a specific form
It could be similar to the last_login field, however, not explicitly set all the time, but switch-on-able by a Meta Class option or something of that sort. Just saying though.
Will like to learn your thoughts