Создание новой модели, имеющей связь один-к-одному с существующей моделью Django
Я хочу добавить отношение модели Profile
через поле один-к-одному к существующей модели User
. Однако у меня уже есть несколько пользователей в базе данных. Как я могу перенести новую модель, одновременно создавая эти отношения по умолчанию?
Например, у меня есть два пользователя Foo и Bar, уже созданные в базе данных, и после миграции модели Profile
оба пользователя должны иметь связанные с ними Profile
.
Модели
class User(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(verbose_name="Email Address", max_length=255, unique=True)
first_name = models.CharField(max_length=255)
surname = models.CharField(max_length=255)
is_active = models.BooleanField(default=True)
staff = models.BooleanField(default=False)
admin = models.BooleanField(default=False)
objects = UserManager()
USERNAME_FIELD = "email"
REQUIRED_FIELDS = ["first_name", "surname"]
def get_full_name(self):
return f"{self.first_name} {self.surname}"
def __str__(self):
return self.email
def is_staff(self):
return self.staff
def is_admin(self):
return self.admin
### New model I want to create
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
avatar = models.ImageField(default="gravatar.jpg", upload_to="avatars/")
username = models.CharField(max_length=255, blank=True)
phone = models.CharField(max_length=15, blank=True)
def __str__(self):
return f"{self.user.first_name}'s profile"
Во вновь созданный файл миграции просто включите RunPython
скрипт, который создаст связанные Profile
объекты для существующих пользователей:
# xxxx_migration.py file
from django.db import migrations
def create_profiles(apps, schema_editor):
User = apps.get_model(<app_name>, 'User')
Profile = apps.get_model(<app_name>, 'Profile')
users = User.objects.filter(profile__isnull=True)
Profile.objects.bulk_create(
[Profile(user=user, username=user.email) for user in users]
)
class Migration(migrations.Migration):
dependencies = [<migration_dependencies>]
operations = [
migrations.CreateModel(
name='Profile',
fields=[...]
),
# Create profile objects
migrations.RunPython(create_profiles, reverse_code=migrations.RunPython.noop)
]
Подробнее о пользовательских скриптах в миграциях здесь