简体   繁体   中英

Cannot assign “<User: user.name>: must be a ”User" instance

I am having an issue writing a custom django migration where I am trying to set a field value for a model to a user. The model in question is shown below (CustomerMachine). This model uses the django-simple-history module to track changes in model instances. I am attempting to query the instance history in the migration and set the review_submitter value to the last user which edited the instance. The result of the history query history_user returns a <class 'django.contrib.auth.models.User'> type, but when I try to set the review_submitter to that value I get the following error: ValueError: Cannot assign "<User: user.name>": "CustomerMachine.review_submitter" must be a "User" instance. Any insight into whats going on here?

simplified class example

class CustomerMachine(models.Model):
    review_submitter = models.ForeignKey(settings.AUTH_USER_MODEL, default=None)
    history = HistoricalRecords()

custom migration

from __future__ import unicode_literals

from __future__ import absolute_import
from django.conf import settings
from django.db import migrations, models
from django.contrib.auth.models import User

from acceptance.models import CustomerMachine

def set_submitter(apps, schema_editor):
    machines = apps.get_model('acceptance', 'CustomerMachine')
    for machine in machines.objects.all():
        history = CustomerMachine.history.filter(serial=machine.serial)
        if history:
            history_user = history.last().history_user
            machine.review_submitter = history_user
            machine.save()

def reverse_func(apps, schema_editor):
        pass  # code for reverting migration, if any

class Migration(migrations.Migration):

    dependencies = [
        ('acceptance', '0031_auto_20200914_1611'),
    ]

    operations = [
        migrations.RunPython(set_submitter, reverse_func),
    ]

migration 0031_auto_20200914_1611

from __future__ import unicode_literals

from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion


class Migration(migrations.Migration):

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
        ('acceptance', '0030_auto_20191218_1927'),
    ]

    operations = [
        migrations.AddField(
            model_name='customermachine',
            name='review_submitter',
            field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
        ),
        migrations.AddField(
            model_name='historicalcustomermachine',
            name='review_submitter',
            field=models.ForeignKey(blank=True, db_constraint=False, default=None, null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='+', to=settings.AUTH_USER_MODEL),
        ),
    ]

The problem is that you are trying to import model into the migration directly:

from acceptance.models import CustomerMachine

In migrations you can only get models like that:

machines = apps.get_model('acceptance', 'CustomerMachine')

This model can be used later:

history = machines.history.filter(serial=machine.serial)

instead of:

history = CustomerMachine.history.filter(serial=machine.serial)

The thing is that in migrations you don't have access to classic models with their state and when you do machines = apps.get_model('acceptance', 'CustomerMachine') you are getting <class '__fake__.CustomerMachine'> which is not your CustomerMachine (you can check with pdb in you migration). And when you are trying mixing you standard models with the "fake" equivalents you have the errors like you described.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM