Hi I am new to Django and building out a stock-control app as a learning tool.
I have a challenge I am struggling to understand which direction is the most correct to head off down to resolve this.
I have two template views residing in two different applications of my overall project.
The first view is a Home Dashboard it has a series of small Dev panels that show various stats about the state of Stock volumes and other items of immediate interest to all Users, for example: Items in Stock, Available Products to order, Ordered Items, Low Stock Items, and finally Out of Stock Items. This view resides within my base app. These panels are dynamic and update as the Home Dashboard page is reloaded.
The second view is a CRUD page that allows an admin user to create and deleted stock items. This view resides in my Stock app.
Within this view is a filter panel that returns stock items based upon various criteria set. One of the filter options is low stock. Low stock is determined by comparing stock numbers (ints) to a variable (also an int) set from a dropdown in the filter panel itself, and thus this returns all rows of stock where the number of items is equal to or less than a number set by the low_stock dropdown.
I would like to have the low_stock variable as a Global variable which is set from the CRUD page in the stock app (so that only Admins can modify it). I’d then like that variable to stick as the application closes and opens. So that once it is set it will remain set until changed.
With this variable assessable to other views across all apps of my project, so that I can filter data and return that to any Dev item I want these filtered results displayed from.
My question is the following. Where should detail like this live:
in a Database table
As a custom Context Processor
As a variable in the Project settings.py file
I’ll only have a few of these Global variables within my entire site, so creating a database table to hold this detail seems over kill. I was hoping to keep the solution lighter if possible.
Advice and recommendations greatly appreciated.
There are no such things as global variables. The idea actually doesn’t make any sense in the Django context.
In a production environment, you are likely to have multiple instances of the Python process running, and, they can be restared at any time. Any data stored within the process is local to that process, and is lost when the process ends.
Store this data in your database. That’s what it’s there for,
And, if these values are to be used in other queries, then they’re already there in the database for use.
I had suspected that would be the answer.
I guess in my mind I was hoping for what I perceived to be a lighter option, like an ini file or a config class that could be stored server side and past forward to be updated only when specific Users logged on, otherwise just read, simpler to the settings.py variables.
Storing this data in a table seems logical for the reasons you have describe, I am just struggling with the reliance on the database for that many data types. I would have preferred to limit data storage within the database to Customer Created data, with custom application configuration parameters held in a non-database location.
I know the argument will be that a table is a degree of separation. I guess I am just not seeing it like that at the moment.
Thanks for the reply.
In the Django environment, there is nothing “lighter”.
It’s not a question of “degree of separation” or any other generic architectural design pattern you may have learned about.
The issue is that it’s the pattern around how Django itself was designed.
An ini file would need to deal with concurrency issues and “locality”. (If you’ve got two instances of the same Django project running on two different systems, then you need to have a way to share those files.)
The settings file is used once - when the system is started. Changing the settings file requires that the Django instance be reinitialized.
I’ve already explained why global variables are meaningless in this platform.
Yes, you could use a common cacheing environment such as redis or memcached - but if you’re not already using them, then that’s something else to be managed in your environment.
On the other hand, Django requires a database. It’s built around the database being available.
So what you would be doing, is to use Django as it’s intended to be used.
That’s not Django’s architecture. Your use of the database is in addition to what Django already uses the database for. (This usage includes, among other things, tracking applied migrations, the ContentType and Permission systems, and tracking admin usage.)
Can you elaborate on this?
@KenWhitesell re “can you elaborate on this”. By way of example if you consider the settings.py file, this one file contains numerous data types, files paths, integers, boolean values, IP addresses, etc. While I accept that these settings once set are static and do not change often. The fact remains that this one file contains many different entities of different types. To do the same in a database will either mean, having each record in a custom config table with extra columns not needed in all cases Or using a single value type of text or char, and doing in client conversions to get back to ints, bools, and links. Or having a table per type to reduce the columns or conversations of each data type. Then having to remember which table a item is in post. All this could be cleaner in my view if a server side file was available for some custom configuration that User can interact with.
You need to expand your perspective a bit. Since Django is designed to be scalable and able to be run as multiple instances on multiple nodes concurrently, managing access to a “file” across all nodes and instances becomes a real problem and far “less clean” than the available alternatives. It’s not a practical or realistic solution in a production-quality deployment.
Ok, so what’s wrong with this? (Answer: Nothing. Been there, doing that.)
It’s not “wasteful” in any meaningful sense of the term. Or, if the number of such settings is so large that it actually is a factor to consider (>100,000), then I would say you’ve got a different or more fundamental design issue that should be resolved.