I am developing a Django app being a Web frontend to some Oracle database with another local DB keeping app's data such as Guardian permissions. The problem is that it can be modified from different places that I don't have control of.
Let's say we have 3 models: User, Thesis and UserThesis.
UserThesis - a table specifying relationship between Thesis and User (User being co-author of Thesis)
Scenario:
User is removed as an author of Thesis by removing entry in UserThesis table by some other app.
User tries to modify Thesis using our Django app. And he succeeds, because Guardian and Django do not know about change in UserThesis.
I thought about some solutions:
Having some cron job look for changes in UserThesis by checking the modification date of entry. Easy to check for additions, removals would require looking on all relationships again.
Modifying Oracle DB schema to add Guardian DB tables and creating triggers on UserThesis table. I wouldn't like to do this, because of Oracle DB being shared among number of different apps.
Manually checking for relationship in views and templates (heavier load on Oracle).
Which one is the best? Any other ideas?
I decided to go with manually checking the permissions, caching it whenever I can. I ended up with get_perms_from_cache(self, user) model method which helps me a lot.
Related
I have a django project and want to divide it into multiple databases with the same structure.
Use url to distinguish different databases. When the admin management page logs in, log in to different databases according to different urls.
For example: 127.0.0.1/admin uses the admin database, 127.0.0.1/admin2 uses the admin2 database.
Does django implement this function? What do I need to do, Can you give me some suggestions or ideas? thank you very much
TL;DR
As far as a single django project is considered, there is no default way to achieve multiple database.
Scenario 1
From your very limited explaination I will assume that you want to seperate data of one admin dashboard from the data of second admin dashboard, to achieve data isolation with respect to permissions & other models, this is called multitenancy.
Very briefly: In a Multitenant architecture you can have multiple tenants whose structure is defined by your models.py and you can control all this tenant via a main superadmin, these tenants can have their own admin dashboard where the data stored in them are only specific to their tenant users. In more simpler terms you can have a SaaS app with this method, where you can have multiple organizations and these organizations have their own users with their specific permissions/groups.
Multitenancy can be achieved in django via a Schema seperated database using POSTGRESql and this awesome package that has already done most of the heavy lifting for you. You can achieve seperate logins via url or subdomain. If your tenants have users who part of more than one organisation and you want a single login for all of them then you can use this package that goes along with django-tenants. It provides a public user table with permission modules separate for each tenant.
Scenario 2
From your very limited explaination I will assume that you still want seperate databases for your app, in such case you need to rethink your approach to the problem because it is not something you will fancy after deployment as there is not direct way provided by django. Instead you should look into micro-service architecture.
I'm a few weeks into Python/Django and encountering an annoying problem. I have some existing databases set up in settings.py, everything looks good, I've even accessed the databases using connections[].cursor()
But the databases (and data) are not making their way into models that I want to use, despite doing the makemigrations and migrate commands. I was able to use py manage.py inspectdb --database-dbname and copied that class information manually into my models.py, but that didn't work either (typing py manage.py inspectdb on its own does not pull up these databases, I was only able to view by that --database extension). So I'm stumped, as it seems I'm doing all the right steps but not able to use these existing databases in Django.
Any other hints and steps I can take are welcome!
(Almost) all the tutorials, examples, and third-party app you'll find on the internet, and most of the Django documentation assume you use one database for your app. That's because it's fairly tricky and unusual to use multiple databases in one app.
But it's not impossible to use multiple databases and the documentation contains instructions on how to do this and what changes you'll need to make to make it work.
IMO, these are the pre-conditions to use multiple databases in one project:
The databases contain explicitly unrelated information, i.e. you won't have SQL relationships between tables in different databases. One database may contain a table with a column that maps to a column in a table in another database, but they aren't explicit (no ForeignKey or ManyToManyField in your models).
You don't need to mix databases in one query: This basically derives from the previous condition. It just means that if you need to get objects from one database that depend on the rows coming from another database, you establish the relationship in python. E.g. fetching as list of names from one database and using that list to filter a queryset on the other database.
For example, if you have an existing database that contains Strava routes (which are regularly updated via some external mechanism) and your app is a broader app that helps users getting to know their neighbourhood where they can recommend locations and things to do, being able to offer a list of routes with a starting point nearby might be something you'd want to show.
Now that you know this, the way to go is described in the doc linked above:
Create a database router so that queries for certain models are automatically routed to the correct database. E.g. Route.objects.filter(start_city=city) would automatically fetch routes from your Strava routes database.
If you need to save information about a route in your app, save it in a model in the default database and use a unique identifier of the route that will map to the strava database. Use separate queries (no relationships) to fetch information about a specific route.
That being said, if the Strava database is not regularly updated via 3rd channels and its purpose is just to pre-populate your default database, then export the data from the Strava database as json and import it into your django db using manage.py loaddata or a migration file, the latter being more flexible as to the structure of the json file.
I'm writing the backend for a SaaS application in django. Need some guidance on the architecture.
So the product will have 2 offerings: a general one where all users will share the same database and a premium one with a dedicated database. How I'm planning to translate this to django is the following:
Within the django project, there'll be one app for the general offering.
For every premium client, there'll be a separate app.
Each app has the same models.
Every app communicates with a separate database. Achieved this using: stackoverflow post and django documentation
I'll write views for all the APIs in the project's views.py, not inside any app and decide on the basis of a token which app's models to communicate to.
The problems I see right now with this architecture:
In all of the views, I'll have to write a lot of conditional statements once the number of premium clients increases.
Onboarding of new premium clients requires quite a bit of code change.
Code duplication in models.py of all the different apps. But it's almost similar to writing statements for creating tables in a new database every time a premium client signs up. Comments?
Please advise me on the architecture as a whole. I went through a lot of articles and stack overflow posts before going this way, but none were completely specific to django so I'm not 100% confident. Much thanks in advance.
If the functionality of the free and premium offerings will be exactly the same you shouldn't need any code duplication. This is of course a big IF, because it's very conceivable that you'll add extra features to the premium offering.
If the functionality will be exactly the same then all you need to do is add any new premium databases to your settings.py and use a middleware to determine which database your models should communicate with (using the using attribute), and for the shared database add an owner column to every table that records who the owner of that row is so you can filter querysets appropriately.
I have an existing app written using django framework.
This app is using django-registration-redux to identify the users.The app is using ORM to work with db.
I have to share the app for more then 1 client.(to make it SaaS)
I am adding a client field in every table and want to have every user assigned to certain only one client.So even if same DB is used different users that belong to 2 different clients will have totally encapsulated data set from each other.
Is there any existing package that can do it?
Try django-tenant-schemas.
It should solve your problem.
I am developing a website which will be used as a multi-tenant system. It will be used by the members of multiple organization. The pages in the system could be different for different organization. I want tos use web2py inbuilt access control system. However I am not able to figure out how do I differentiate users as per the tenants. I cannot mention tenant in auth_user as a single user may have access to multiple tenants(in case of super admin). I also cannot mention it in auth_group table for the same reason. What I think is that I can do it in auth_permission table by mentioning tenant in the name field of that table. Will it be a correct approach? Please suggest me if you have any solution to this.