Django: Force table creation order on syncdb - django

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.

Related

How do I have the deletion of a user in Django trigger execution of some additional code?

In my Django application, when a user is created, a database is created too. This is defined in my registration view. I have the database creation to make up for the lack of support for dynamic models. My problem is that I want to have the deletion of a user in the Django admin page call some code which will also delete the database. I am not sure how to do this.
Depending on what code you want to call, consider post_delete as an option, if it doesn't metter for you where object being deleted or overriding delete_model method, in case you want to run this code specifically during delete via admin.

How to migrate default user data to custom user model in Django

As I want to customize Django user model, I migrated from default user model to my own custom user model. Since my Django project has been working since a long time ago, I need to keep the existing user data.
I was thinking to move them manually, but Django default user model's passwords are hidden. How can I safely move existing user data to my custom user model?
Moving to CustomUser is no easy task in Django. If you want to keep the existing data, then as per ticket #25313, you need to do the following steps:
Create a custom user model identical to auth.User, call it User (so many-to-many tables keep the same name) and set db_table='auth_user' (so it uses the same table).
Throw away all your migrations from all the apps(except for __init__.py file inside the migrations folder).
Recreate a fresh set of migrations(using python manage.py makemigrations).
Make a backup of your database.
Delete all entries from django_migrations table from DB.
Fake-apply the new set of migrations(using python manage.py migrate --fake).
Optional: Set db_table="your_custom_table" or remove it altogether.
Make other changes to the custom model, generate migrations, apply them.
You can dump your existing model data with dumpdata command and also able to reload those data to that model or your changed custom model with loaddata command. Here is a good example how you can able to do that. link

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.

Auth_User v/s User table in Django

I am learning Django, and i am following the Django tutorials in the djangoproject website. I wanted to use the Django Auth. In the tutorial I saw a reference to a User table which will get created automatically during the 'migrate' if I have all the needed settings. I made sure all the settings are inside the settings.py file and ran migrate. I saw that instead of User table, it is Auth_User got created inside the database. I want to hash the password before storing it in the database, for that I tried using set_password function, which is not available with the Auth_User.
Can any one please tell me the difference between Auth_User and User
Methods are defined on the model class, not on the database table. The User class creates a table called "auth_user", because it is inside the auth app. And the set_password method is available on that model.
I think your confusion is coming from the fact that User is a class of the auth app.
As seen in the Django documentation, the app name is prepended to the start of the table name:
For example, if you have an app bookstore (as created by manage.py
startapp bookstore), a model defined as class Book will have a
database table named bookstore_book

Adding fields to user's personal info in Django admin page

I just started a Django project (there are no apps in it). I activated the admin in settings file and can access the Django administration page. There is a column in Django page to add users; while adding users I get only three fields under personnal info, but I need to store some more information about users. I Googled around and found that I can use user profiles to accomplish this. I tried, but I am having problems.
My aim is to add three more fields to the user table:
role
contact number
other
I need details like: which function I need to write and where to do this.
I found this, but I do not know where I need to write these steps. I would greatly appreciate a more clear explanation of this.
Django User Profiles is what you need. The blog you linked to has clear steps on how to do it. You can check out the Django documentation. http://www.turnkeylinux.org/blog/django-profile also provides a good explanation.
Basically you need to create a new model with User as ForeignKey and define the model in the settings.py as AUTH_PROFILE_MODULE = "django_app.your_profile_modelname". Create the profile and save it just like any other model, and access it using user.get_profile()
Adding a couple of things in response to your questions below:
First, do not create apps as a directory. Use startapp <appname> [destination] as described here. That will create the app directory.
Second, you have to add the app to INSTALLED_APPS in the project's settings file, do a syncdb. Basically, follow the steps in Django tutorial on writing your first app.
Third, UserProfile is a separate model. It is not an extension of User. It is associated with the User just because you added User as the ForeignKey.
Fourth, to be able to see the user profile model in admin, you do exactly what you would do to add any other model to admin page. Create a file names admin.py under your app with:
from django.contrib import admin
from myproject.app.models import UserProfile
admin.site.register(UserProfile)
There are three key concepts to understand:
There is no built in "profile" system in Django, beyond the limited auth app which is really geared just to user login. You are expected to roll your own.
There is nothing magical about a profile record in itslef, it is just like any other record that takes User as a foreign key (or, more properly, a one-to-one field as per the docs). You create it by creating a custom django app (traditionally called profiles) and a model for that app (traditionally called UserProfile, since Profile is not allowed as a model name).
The only thing that sets UserProfile aparts as a model is that you specify it as the AUTH_PROFILE_MODULE which means that it is accessible when called .get_profile() on a User record. That's it. If you set up the UserProfile like so:
def UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
other fields
then you can also access the profile as user.profile rather than user.get_profile() which some people prefer.
Again, nothing magical about the profile model -- it is just a model record like any other model record.
If you want to be able to edit additional fields within the user form that's more complicated; easiest way is probable unregister User and then register it again using your custom ModelAdmin and form class but judging by your question you're probably not at that level yet.