I'm developing a project with django where each user is supposed to have one database.
I found a way to do so :
Fill the settings/dev.py with all databases (one per user)
Use the database router class to route the database to the models to the corresponding database (except the user model which will be redirected to a constant 'users' database of course because it is used to log in)
So when someone creates an account in our website and clicks the verify link sent by mail, it is supposed to query the server to run "manage.py create user", create a database for this user, change settings/dev.py to add the db to the list and finally perform a migration to create the db. Then, the user is redirected to the login page and is logged automatically with its credentials.
But i'm asking myself if is the best way to do that ?
Would we rather do the following ?
Create one app (copy files + settings/dev.py) for each user and determine which app to use from an http header or a subdomain (user.site.com) or a port, etc.
Use one database and create a user_id column in each table
Which one is the better for performance, scalability, security etc. ?
Thanks.
Related
Currently I implemented a login routine for the website I am working on, according to This Tutorial.
Also I am not authenticating the user with djangos own system, because I am using authentication against the LDAP of my company (django-auth-ldap).
Currently I am using a general user to login to the database, which has universal access to all data, which also gives full access to any user logging in to the website.
To avoid that I would like to know how I can connect to the database as the individual user, who just logged in to the website.
Thanks in advance and sorry for bad english
Restricting user access to functionality and authenticating with the DB are handled separately in Django. You might be able to read the privileges of your users from the DB and map them to Django permissions but this is non-trivial (about Permissions see https://docs.djangoproject.com/en/2.1/topics/auth/default/#permissions-and-authorization).
In a UI/UX that has functionalities restricted depending on authorization, the frontend and backend need to be aware that permissions need to be checked and missing authorization needs to be communicated in some way or other to the user.
Example:
Users in group A are allowed to delete X. They see the "delete" button and there might also be an AJAX call that can delete X.
Users in group B are not allowed to delete X. They do not see the delete button and the AJAX call that can delete X needs to check for that permission and/or user group membership.
If you are only using a DB level authorization layer than - how would you know if the "delete" button should be displayed and for what to check in the AJAX call?
hi!
If I'm getting your problem correctly, the user you are creating is a Super User every time right?
Well if you are using Django auth.User model, you can just make User_object.is_super to False and then restrict the access of users though if-else in view! (User_object is the object of the auth.User model)
Does that made any sense?
//BTW, a side-note, a mistake I made while making my first custom user model: make sure to store your passwords hashed using Django hashes and salts!
I am reading the Tom Aratyn Book - Building Django 2.0 web application. I am on a basic level.
Before migrating my app to the database, he asks to create a database for our Django project. I didn't understand very well how to create this database, he didn't detailed the process. Follow what he says:
" Now that we have a model, we will need to create a table in our database that matches it. We will use Django to generate a migration for us and then run the migration to create a table for our movie model.
While Django can create and run migrations for our Django apps, it will not create the database and database user for our Django project. To create the database and user, we have to connect to the server using an administrator's account. Once we've connected we can create the database and user by executing the following SQL:"
CREATE DATABASE mymdb;
CREATE USER mymdb;
GRANT ALL ON DATABASE mymdb to "mymdb";
ALTER USER mymdb PASSWORD 'development';
ALTER USER mymdb CREATEDB;
I don't know where to type this line of code. Shell? I know his book uses the PostgreSQL database.
Thank you,
To execute commands on the database, you need some kind of client. If you have access to the database server bash, you can use the command line client psql.
For clients with a GUI, pgadmin is the most common. On the interface, you are able to open a window, in which you can insert the SQL commands.
So I'm starting a new Django project that essentially requires the login & registration process be routed through an EXTERNAL & ALREADY created database.
Is it possible to have the User model use an EXTERNAL database table ONLY when Django is:
Logging in a user, to check if the login is valid
Registering a user, inserting data for that user in the external database
I would like for the rest of the Django server to use a local database.
If so, could someone either provide examples or guide me to documentation on the subject?
Easiest way to use multiple database with Django is to use a database routing. By default Django stick to single database, however, if you want to implement more interesting database routing system, you can define and install your own database routers.
Database routers are installed using the DATABASE_ROUTERS setting. You have to specify this setting in your settings.py file
What you have to do is write one AuthRouter as described Django documentation Django Multiple Database
"Yes, but"
What you are looking for in the docs is called "database router".
There is even an example for the auth app in the docs there.
But, there is s serious drawback to consider with this approach:
We cannot have cross-database relationships in the models. If auth tables are in a separate database, this means that any otehr app that needs a foreign key to User model is going to run into problems. You might be able to "fake" the relationships using a db that doesn't enforce relationship checks (SQLite or MyISAM/MySQL).
Out of the box, such apps are: session, authtoken, and admin (and probably more).
Alternatively, a single-sign-on solution might do a better job: django-sso, or django-mama-cas + django-cas-ng, or the commercial Stormpath.
I'm currently connecting to a Postgres db from a Python script and I'm using sqlalchemy with psycopg2:
postgresql+psycopg2://user:password#host:port/dbname[?key=value&key=value...]
This Python script is available to users, and the password is shown in clear text. How can I use an encrypted password instead?
Generally, this is done in a few different ways.
1. Hide your database behind a REST API
Basically, don't make the database directly accessible to users. Provide an interface like a REST API or something similar for users to interact with the database. The username and password are only stored on the server side.
2. Create another DB user with less privileges and only distribute that user.
Your postgres database can have multiple users. Don't give them the user and password for the db owner. Just create a user with less privileges (read-only maybe?) and distribute that user and password.
I'm planning to develop web UI something like iSQL*Plus-oracle but, for most common databases. Just take input query from user and return result with save options,etc.
So, for connecting to external data bases, what is advisable way,
1. Using django model and raw sql or,
2. with modules outside django - sqlalchemy+mysqldb,psycopg..?
Going through django documentation my understanding is db connections has to be in settings.py and I could not add from user input. Is my understanding is true or not?
I'm new to django not to python.
An ORM (something like Django's models or sqlalchemy) is a really helpful abstraction to help map tabular data in the database to the objects its being used to model in your code. It won't help with connecting to databases provided by the user since you won't know what the schema of the database is you're connecting to, nor what you are going to receive back from a query.
With django, the database defined in settings.py is used to store information related to your app such as user credentials, migrations as well as whatever else you define in your models.py files. So definitely don't try to change that dynamically as it is being used to store the state of your application for all users.
If you need to connect to external databases and run user-supplied queries, you can do that inside a view using the appropriate database driver. So psycopg2 for postgres would be fine.