Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django 2.1 how do I create a user in a migration

I'm trying to add a new user and then associate it to a subset of existing records.

For example, imagine I have this app model:

class Foo(Model):
    user = model.ForeignKey(User, default=None, on_delete=models.CASCADE)

In my migration I have:

from django.contrib.auth.models import User    

def add_user(apps, schema_editor):
    anon = User.objects.create_user(username='anonymous')
    anon.save()

    Foo = apps.get_model('myapp', 'Foo')
    foo_to_change = Foo.objects.filter(user_id=1)

    for f in foo_to_change:
        f.user = anon
        f.save()    

When I run this I get this error:

ValueError: Cannot assign "<User: anonymous>": "Foo.user" must be a "User" instance.

I thought the problem might be that I'm using the User model directly and the docs say not to do this. So I changed the top part to:

User = apps.get_model('auth', 'User')
anon = User.objects.create_user(username='anonymous')
anon.save()

Now I get a different error:

AttributeError: type object 'User' has no attribute 'normalize_username'

What am I doing wrong? How do I add a new user in a data migration?

EDIT: I'm using sqlite as DB

like image 329
Ben Avatar asked Oct 29 '18 03:10

Ben


People also ask

How do I create a custom migration in Django?

Run python manage.py makemigrations to create a migration file. This is an auto-generated migration file using the above command. Now we will add function for transferring data from users table to bank_accounts table.

What is difference between migrate and migration in Django?

You should think of migrations as a version control system for your database schema. makemigrations is responsible for packaging up your model changes into individual migration files - analogous to commits - and migrate is responsible for applying those to your database.


1 Answers

You can do something like:

def add_user(apps, schema_editor): 
    apps.get_model('myapp', 'Foo').objects.filter(user_id=1).update(
        user=apps.get_model('auth', 'User').objects.create_user(username='anonymous')
    )

This works because in this case "no type is checked", the query will use a reference to the entry in the DB instead: the ID of the user.

like image 129
trinchet Avatar answered Oct 17 '22 00:10

trinchet