I want to build a Django application in which each "set of users" can see different data, as they were using different DBs. Is there any best practice to achieve this?
E.g.
user A, after logging, sees and manages his own data, with no possibility to see other's data.
I could use Django multi-db feature to define several dbs and create an automatic router to point to the correct db according to the user of current request (keeping auth_user on a common db).
As last chance, I can make a different application folder for each group (the only difference being the database name), but I prefer a smarter solution.
You could consider reusing one of the many per-object permission apps for django.
Another possibility is to make different settings files. For example, settings_groupA.py:
from settings import *
DATABASES = ...
And then you could use management commands, like syncdb, or runserver, etc, etc ... with the --settings option:
--settings=SETTINGS The Python path to a settings module, e.g.
"myproject.settings.main". If this isn't provided, the
DJANGO_SETTINGS_MODULE environment variable will be
used.
Examples:
./manage.py syncdb --settings=settings_groupA
./manage.py runserver --settings=settings_groupA
The advantage of using one database per set of users is that you can keep your code easier and let them have native support for django.contrib.admin with no hack. But then if you're going to have per-object permissions within a group anyway then you might as well go straight for the first solution.
Related
I've read in some articles that it's best practice NOT to add DB users via flyway db migration. It's not very clear to me as to why it's not a good practice. One thing we thought about is that it might be good to have the user configuration automatically documented in the code.
One article mentioned that you might want different user configuration for different environments. But you could also control that in flyway.
When/why would you not want to add DB users using flyway DB migration?
If I'm deploying a new user for the database that will be common across all environments, I would absolutely make the creation of that user a part of the Flyway deployment scripts. It fundamentally makes sense. "Version 43.43 is where we added the login snarglegrass to the app."
On the other hand, if you are working on setting up different environments with varying permissions, I probably will make that part of the flow control commands in pre/post deployment scripts instead of using Flyway. The reason for this is because it can be challenging to write the scripts in such a way as they're repeatable and safe. You could still do it that way though.
I heard of about Django Custom Management script in lots of community and i am not getting why should i write custom management script as django manage.py a lot of useful command? I am very new in django...
Can anyone tell me some usecase of custom management script?
Thanks
The documentation on Writing custom django-admin commands mentions:
Applications can register their own actions with manage.py. For example, you might want to add a manage.py action for a Django app that you’re distributing
Usually those commands are used for "maintenance" activities. Or to give administrators more convenient tooling.
For example, you can use django-unused-media [GitHub]. This will add an extra admin command, that you can use like:
./manage.py cleanup_unused_media --noinput
This will then remove media files that are no longer referenced. You can then make a cronjob that for example each week calls that command to clean up media files. It thus here can help you to reduce disk space usage, without having to interfere yourself.
Another use case is to make management of your server more convenient. In fact makemigrations [GitHub], migrate [GitHub], makemessages [GitHub] and runserver [GitHub] are managment commands as well. So you probably use these commands all the time.
You put a certain amount of logic into these that is useful, and that you want to repeat several times. So instead of defining migration files yourself each time you change your model, you can implement the logic once to write such commands, and then the developer/administrator, can run a convenient script to do some work.
My system consists of two applications which are separate Django projects (let's say A and B) with own default databases and own users. Application B also reads from the application A database replica.
To achieve such behaviour I included application A into B's INSTALLED_APPS and can access db replica through its models. But everything that is related to users (permissions, groups) is messed.
Does using django.contrib.auth in both applications led to this behaviour, and is there a better solution to work with replica through Django ORM?
Indeed there is a better way. In django world it called DatabaseRouter.
You can read about it here: https://docs.djangoproject.com/en/2.1/topics/db/multi-db/
It is a very comprehensive guide how to achieve multi db env for your django app.
And you can always write custom DatabaseRouter class which allows you to define behavior like: read only, write only, full access per app label, or even your model name.
You can even do this manually (but I will not recommend this for you - as this probably require a lot of changes in the current codebase:
>>> # So will this.
>>> Author.objects.using('default').all()
>>> # This will run on the 'other' database.
>>> Author.objects.using('other').all()
Hope that help - if you have more questions - please ask.
I can think of three reasons why:
providing users with the flexibility on "when" to commit model changes
debugging modularity
perhaps resource consumption in larger
databases
However, it does seem that migrate always follows shortly after migration (tutorials/youtube videos).
so is there a philosophy behind this that I'm missing?
Ofcourse there are some reasons.
First of all, 'makemigrations' doesn't touch real DB, it just tells django how models(db scheme) have changed so you can see what's going on when you do 'migrate'.
and this makes django more safe.
This also provides to make default options for new fields or db changes..
Other reason is 'revert'.
If you want to roll-back db scehme with specific migrations, you can just tell django to roll back to specific migration file.
Another reason is 'reusable-app' principle.
If you create app with django and it could be reusable with no-db-interaction. It means if you deploy your app(or project, too!) to another project or server, it just needs 'migrations' files not real db.
There are many things that are different in deployment and production. For example, in case of using Facebook API, I need to change id of application(because there are different id for testing and production) every time I push update to the app.
I update only app, so what do usually django developers do in this case? Possibly saving a variable to settings.py and then getting it from there or creating separated file in virtual environment folder, which in my case at least is also separated ?
There is no official way of splitting your Django settings for prod and dev -- developers are encouraged to find a way that works for them. The Django docs list out several good options here: https://code.djangoproject.com/wiki/SplitSettings