Django: Create connection between old and new application model - django

The situation:
I have a database with thousands of users.
I have created a new application called 'my_app'.
my_app has one object called 'my_Object'.
my_object has an a relation one_to_one with the Django User.
class my_object(models.Model):
user = models.OneToOneField(User)
My question is:
How can I create a register for all users already on the database? I know I can use post_save for the new ones, but how can I relate / connect this new object backwards?
Thanks!

Run a SQL query in your favorite database manager that creates records for all the existing User records.

Instead of doing from MySql you could also do it from the django shell. Access all the records from the old user base as a query list and then create a my_object for them. As answered above there is no need for setting the signal, as the task has to be done only once. Also such an app based signal, if possible would be more cumbersome to do.
old_users = Old_users.objects.all() for user in old_users:
object = my_object(user = user)
object.save()
By the way, how have you added the old users to django user?

Related

How to remove all users and reset the primary key of user table in django?

I'm developing a django application with some complicated user interactions and multi user types . So this requires a lot of testing to do . I've observed that even after deleting the user's table completely if I add a new user, the primary key of the newly added user isn't 1 . Is there an easy way to completely delete and reset all the primary key indices of the use table ?
Details :
Django version = 3.0
Using the default User model provided by django
Using dbsqlite3
Thanks
You also need to delete the migrations folder in whichever app you have defined your custom users.
In the app foo, the folder foo/migrations contains all the data that you already changed and stored, for it to be a complete reset you must delete those.

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.

django_auth_ldap vs postgres db using django models

I am creating an app where I store the USERS in a Postgres database with the help of the standard User Model, in my Django app i use Django queries to get all needed information, like "first_name", "username" .. etc
I implemented Django_auth_ldap to start storing user identification data in an Openldap server if i want. But now, i'm confused to how to get the data i used to get using django queries. i don't want to change the behavior in my views, i want to continue using Django queries
This looks like it describes some of what you want: https://django-auth-ldap.readthedocs.io/en/latest/users.html
You can perform arbitrary population of your user models by adding listeners to the Django signal: django_auth_ldap.backend.populate_user. This signal is sent after the user object has been constructed (but not necessarily saved) and any configured attribute mapping has been applied (see below). You can use this to propagate information from the LDAP directory to the user object any way you like. If you need the user object to exist in the database at this point, you can save it in your signal handler or override get_or_build_user(). In either case, the user instance will be saved automatically after the signal handlers are run.

Why does django need a database for custom authentication backends?

I implemented a django custom authentication backend. My authenticate() returns a user object like this return User(username=username, password=password), but I never store the User object to a database.
Why do do the django docs recommend creating a database with user objects? (https://docs.djangoproject.com/en/1.4/topics/auth/#writing-an-authentication-backend - "...the best way to deal with this is to create a Django User object for each user that exists for your backend...")
If I try calling login(), there's a call made to the database. If logins are stored in sessions, why is a database necessary? (Using cached sessions)
The reason why you specifically need to save the User object is that it's common for apps to create database level relationships between objects and users (in order to persist the relationship across multiple requests).
A simple example would be the activity log in django.contrib.admin. It displays recent behaviour that users have performed. This only works when the user object is saved to the database.
Quite a few apps have a foreign key to auth.User; if you don't have that table populated then you don't get to use those apps.

Django: Force table creation order on syncdb

I have a Profile model that is used to define a profile for a User from the auth application. Also, I have a signal that will create an empty profile each time a user is created.
The problem is that, when starting from clean, the Profile table is created after the User table, so, when I am asked to add the super user, my signal function fails, because there is no Profile table to enter the empty profile.
Is there a way to force in which order the tables should be created by the syncdb, so that the profile table should already be created when the super user is added ?
Do one of the following:
Modify your signal to catch this specific error (table does not exist) and ignore it. Won't help if you need to have Profile for superuser too.
Do not insert any data before whole DB schema is initialized. You don't have to create superuser during syncdb, this can be done later from dev console (django-admin.py shell) or you could put superuser's User and Profile to your app's initial_data.json fixture that is loaded automatically during syncdb. This will reset it's information on ever syncdb, but in certain cases it's acceptable.
Use AutoOneToOneField from django-annoying lib to automatically create Profile the first time it's accessed. This is how I'd solve this problem myself -- no need to redo existing functionality with signals. Here's an example from their wiki:
from annoying.fields import AutoOneToOneField
class MyProfile(models.Model):
user = AutoOneToOneField(User, primary_key=True)
The order in which the tables are created depends on the order in which you have them in your INSTALLED_APPS
Try moving your app with Profile above django.contrib.auth
Unless you are using a database with Foreign Key checks, in which case the User table may need to be first.