Django 1.8 IntegrityError when adding new user - django

I moved an old Django app from 1.4 to 1.8 and everything in the main application ran fine. I then needed to copy everything from server 1 to server 2, and in the process just dumped the mysql data for the admin database and installed to the new database.
Everything came up fine, however when creating a new user I get:
IntegrityError at /admin/auth/user/add/
(1048, "Column 'last_login' cannot be null")
This is a live system with 30 accounts. I found a variety of solutions to this online but I want to make sure it doesn't trash my database.
I only need the admin database fixed up. My business side database and tables are not managed by Django, but is a custom schema (that I inherited).
btw, deleting a user works fine.

This is described in the release notes, along with the steps to migrate your database to allow null values:
The AbstractUser.last_login field now allows null values. Previously, it defaulted to the time when the user was created which was misleading if the user never logged in. If you are using the default user (django.contrib.auth.models.User), run the database migration included in contrib.auth.
If you are using a custom user model that inherits from AbstractUser, you’ll need to run makemigrations and generate a migration for your app that contains that model. Also, if wish to set last_login to NULL for users who haven’t logged in, you can run this query:
from django.db import models
from django.contrib.auth import get_user_model
from django.contrib.auth.models import AbstractBaseUser
UserModel = get_user_model()
if issubclass(UserModel, AbstractBaseUser):
UserModel._default_manager.filter(
last_login=models.F('date_joined')
).update(last_login=None)
Your error suggests that you haven't run the migration that will allow null values for that column.

Related

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

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

Connecting and importing models from multiple database connections Django

In a django app, I have two postgresql databases connected through settings.py: one is default and other is AppDb. AppDb is placed on a remote machine.
I want to query from a 'Courses' model from AppDb using 'using()' and 'Courses' model is not available in default database.
So my query goes like this:
courseInfo = Courses.objects.using('AppDb').filter(cuser_id = 12)
But I am getting NameError for 'Courses'
Can I have a solution for such queries without using routers
If you have an existing database, you still need to create an app and models for that database in order to use the ORM.
To help you create the model classes, you can use the inspectdb management command which will try to guess the models from an existing database and create the models.py for you. Its not perfect, but it will save you some time.
You will still have to make sure the models have a primary key and are written in the correct order (so that foreign keys will work correctly).

Django built-in User Model implementation

I'm trying to use the built in User model provided by Django in my app, but I'm not sure how to implement it (i.e., what does my models.py file actually look like?) I'm starting off by building a simple login form with the Django auth system.
I'm seeing multiple examples on the web where they import User but never define anything. Like so
from django.db import models
from django.contrib.auth.models import User
#nothing similar to defining User (i.e. 'class User: #fields')
What I'm assuming is by importing User, you don't have to define anything, since it's already been defined, but when I go to run "python manage.py sql 'name'" nothing is executed.
You don't need a models file for the user, because Django already supplies one. You just need to ensure that django.contrib.user is in INSTALLED_APPS.
The only reason you would need to import User into another models file is if you wanted to add a ForeignKey from one of your own models to the User model. In all likelihood, you do want to do that eventually; but you don't need to just in order to get the user models created.

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.