Django app has multiple database and multiple user - django

I have written one Django cloud based app. This app will have multiple user and for them multiple database, so that their data should be separate and they can save only to same database.
1) How can we implement it
2) How to automatically one user from login page to assign the database to write on it.

I don't have a complete answer, since you do not give a lot of detail. But here are a couple ots that f hinDjango supports custom database router implementations. A database router is a class that helps django decide which database to use for a particular model. Unfortunately I don't think this mechanism is granular enough for your needs. You can also specify the database to use in your code by using using(name) queryset method and save(using=name) form of save() method for instances. Of course this also means that some features of Django are going to be unvailable to you, since you cannot always expect to have a user. Look at the docs here for more info
https://docs.djangoproject.com/en/dev/topics/db/multi-db/

Related

Django: Last modified by and created by user automatic saving

The age-old question: How can I automatically save last_modifed_user in django models?
I found in several places this general process how to do it using thread local. I'm hesitant to simply implement it that way because I'm not entirely sure of the consequences it has and because all these posts are old.
Is using thread local still the "recommended" way of doing this in django 3? Or does django3 have a better options of doing it?
No, this hasn't changed. Simply because separation of concern is an architectural principle of MVC (model-view-controller), which is also how Django (model-view-template) and most web frameworks with ORM are architected. Models know nothing about the request, it's not available (and in many cases there isn't a request at all when a model is saved, think of management commands or regular tasks running in the background).
The alternative to thread local is to make sure you implement it yourself in the controller layer (view layer in Django):
Create a view mixin that you can mix with all the generic views that use the ModelFormMixin to save the user into the model (ModelFormMixin.form_valid()). Or combine it with a form mixin where the user is passed to the form (FormMixin.get_form_kwargs()) and saved when the form is saved (ModelForm.save()).
Create a ModelAdmin mixin that does the same when saving a model in the django admin site.
This of course means someone on your team may forget to do it when creating new views and forms. The link you posted contains an answer as to the advantages and disadvantages of using thread local.

How to dynamically swap default database on the model manager in django?

I am creating a project in django and django rest framework. Its an api for an angular app. The database setup consists of multiple databases. one is default database, all the django tables reside in this database; rest of the databases belong to a type of a user, each user is supposed to have a separate database. So, all the user related data goes to its separate database. To implement the selecting database dynamically, user object has an extra field to store the database to write to.
from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
"""Custom User model."""
database= models.CharField(max_length=9)
Reason for doing this was performance improvement as each database is separate, ListView and DetailView would work faster than if the data was stored in the one database only.
I know I can choose a database to store by using the using method on the model manager. In the rest api things work fine and data is being stored in their separate databases, but I end up overriding methods that django has defined. Its adding development cost to the project. Foreign keys and ManytoMany keys needs to be resolved with the current database of the user, which is not happening as I have customized the database setup. Also, my code cant be as good as theirs :p , as they have written django over the course of many years.
I have overwritten many querysets already, but django still uses default database many times. If only I could use the request object in the model manager of django models to swap the default database on per request basis, things would be different i think.
My questions are -
Is there a way to access the request object in the model manager? I could do something to the effect of below code.
class CustomManager(models.Manager):
def get_queryset(self, request):
return super(CustomManager, self).using(request.user.database).get_queryset()
Model manager has _db property that could be used to select database. Would overriding it is advised? if yes, how and where in the code?
Is there a better way to implement the separate databases?
Thanks in advance.
Regards
Using a database router is recommended in Django docs, but the problem is it only accesses the model class.
Found a couple of questions related to the problem of switching databases dynamically. This post has a solution that would solve the problem of passing the request.user or any other parameter by using a threading.local instance.
Someone created a reusable plugin even for this - https://github.com/ambitioninc/django-dynamic-db-router
Hope that helps.

Adding permissions to Django model without table

I'm working on some Django Rest Framework based project (quite expected API for some web-app). It has as traditional Django models, and some kind of model-like objects: they behave like Django models but don't store anything in DB. No tables, no content-types. When we ask them for objects, they goes to external API and forms resulting Queryset.
Now I need to build some role-based access system. To make the architecture clear and extensible, I want to make groups and permissions managable through the Django Admin interface. So, I guess, we need to put some permissions to DB and then we'll be able to add these permissions to user groups. After that, we'll check these permissions in DRF.permissions class. But since we have neither tables, nor content-types for these 'models', we can't add records to permissions table right now.
What is the right way to make this possible? Should I rebuild these 'models' through the metaclass with proxy = True? Or should I add a proxy layer above? Maybe I should add some dummy content-types by hand?

Django Mongodb Engine : Authentication, Sessions ans User Model

I'm new to Django and Mongodb seems really cool and I have a few
questions ! I'm using Django nonrel with Django Mongodb Engine.
I hope I'll not make too many mistakes :)
1 ) Are the Django user authentication system and the Django Session
system working fine ? Because I see on allbuttonspressed.com that
there is a problem with authentication and admin interface and the
part with the 3rd party written authentication backend makes me think
that the django authentication system doesn't work with mongodb :
You can only edit users in the admin interface if you add
"djangotoolbox" to your INSTALLED_APPS. Otherwise you'll get an
exception about an unsupported query which requires JOINs.
Florian Hahn has also written an authentication backend which provides
permission support on non-relational backends. You should use that
backend if you want to use Django's permission system.
2) If the authentication system works fine, how can I add fields to
the user model ? I saw on the Django docs that to achieve that the way
to go is to define a model with a OnetoOnefield to the user model
( "user = models.OneToOneField(User)" ) and define the other fields we
want in that model. I get it that must be the right way with SQL
databases. But with NoSQL like mongodb that just seem wrong to me, if
I'm not mistaken it creates a new collection and puts in each document
an user field used to link the document to the document in the User
collection ( exactly like a foreign key ). That doesn't seem to be a
NoSQL way at all ( Well It's just my feeling but since I'm just a
beginner I may be wrong, don't hesitate to correct me ). Is there a
recommended way to add fields directly to the User model ?
3) When the Model is used in Django, it puts all the fields in the
document even if they are empty right ? Isn't that a waste of space to
write down a lot of fields names in documents if they are empty ?
4) This question is more about Mongodb itself than the engine but I'll
ask it anyway, you may have the answer : How much extra space does it
take to index a field in a collection ?
Didn't think I would have written so much, I hope some of you had the
courage to read me !
Thanks in advance,
Nolhian
Only a partial answer as I don't use MongoDB.
I'm using django-nonrel in a Google AppEngine project. I'm using those other custom apps like "djangotoolbox", and some backends for GAE. Admin panel and standard Django authentication are working very well. I suspect it's the same for MongoDB (like mentioned in the quotation you have provided)
You're right. The standard approach is definitely good for relational databases, but might not work or work inefficiently for NoSQL databases. The typical scenario is to duplicate the data to another table, so you don't have to do JOINs. I think you can simply subclass the User model and add your fields to your custom model (docs).

How to implement non-database backed models in Django?

I have an existing Django application with a pretty typical model implementation that's backed by a database. My task is to change this model so that instead of fetching the information from a database, it now fetches it from a service (e.g., via HTTP). Because there is existing code which already makes use of this model, it would be nice to maintain the same model interface so that it continues to behave like a typical Django model.
This raises a few of questions:
Is it possible to do this without having to re-write the interface from scratch to make it look like Django's model interface? (This stackoverflow question would seem to suggest otherwise: Django MVC pattern for non database driven models?)
Would writing a custom manager for this model be an appropriate approach (or have I misunderstood the role of the manager)?
Due to the service-backed nature of the new model, caching will be much more important than before. Is this something that should be implemented at the model level?
Have a look at django-roa. From the sound of it, it might be exactly what you are looking for.