gpt4 book ai didi

python - 编写一个 Django 迁移,添加一个基于另一个字段的唯一字段

转载 作者:太空宇宙 更新时间:2023-11-04 09:42:39 25 4
gpt4 key购买 nike

我有一个模型 SessionCategory,它有一个唯一字段 name。此模型的某些关键实例由 name 引用;唯一的问题是 name 在我们的内部仪表板中也是可编辑的,因此用户可能会通过更改 name 无意中“破坏”这些引用。

为了解决这个问题,我想创建一个新字段 name_slug,它是 name 的 slugified 版本,也具有唯一约束。我已尝试执行以下操作:

from django.db import models
from django.utils.text import slugify
from django.db.models.signals import pre_save
from django.dispatch import receiver



class SessionCategory(models.Model):
name = models.CharField(max_length=255, unique=True)
name_slug = models.CharField(max_length=255, unique=True)


@receiver(pre_save, sender=SessionCategory)
def create_name_slug(sender, instance, **kwargs):
if not instance.name_slug:
instance.name_slug = slugify(instance.name)

我在其中添加了 name_slug 唯一字段。问题是,如果我尝试 python manage.py makemigrations,我会收到以下提示:

(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py makemigrations
You are trying to add a non-nullable field 'name_slug' to sessioncategory without a default; we can't do that (the database needs something to populate existing rows).
Please select a fix:
1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
2) Quit, and let me add a default in models.py
Select an option:

我在 https://docs.djangoproject.com/en/dev/howto/writing-migrations/#migrations-that-add-unique-fields 遇到了一个工作流用于编写创建唯一字段的迁移。在该示例中,唯一字段是使用“通用”函数 uuid.uuid4() 生成的。然而,就我而言,我需要访问特定实例的 name,就像我希望通过连接到 pre_save 信号来获得一样。

如何创建此迁移并维护唯一约束?

最佳答案

我认为 RunPython 该功能将为您提供帮助。

第一步。在添加 name_slug 之前,您已经有一个迁移文件字段。然后创建一个新的迁移文件,name_slug = models.CharField(max_length=255, unique=True,<b>null=True</b>) .文件会是这样的

<强> app_name/migrations/0003_some_name.py

from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('sample', '0006_sessioncategory'),
]

operations = [
migrations.AddField(
model_name='sessioncategory',
name='name_slug',
field=models.CharField(max_length=255, null=True, unique=True),
),
]

**第 2 步。** 使用 `RunPython` 添加自定义迁移脚本,如下所示,
from __future__ import unicode_literals
<p>from django.db import migrations, models
<b>from django.utils.text import slugify</b></p>
<p>class Migration(migrations.Migration):
def forwards_func(apps, schema_editor):
SessionCategory = apps.get_model("sample", "SessionCategory")
for instance in SessionCategory.objects.all():
if not instance.name_slug:
instance.name_slug = slugify(instance.name)
instance.save()</p>
<code>def reverse_func(apps, schema_editor):
pass</b>

dependencies = [
('sample', '0006_sessioncategory'),
]

operations = [
migrations.AddField(
model_name='sessioncategory',
name='name_slug',
field=models.CharField(max_length=255, null=True, unique=True),
),
<b>migrations.RunPython(forwards_func, reverse_func

)</b>
]</code></pre>
</code>

<br/><br/>
<strong>Step 3.</strong> do the migration by <code>python manage.py migrate</code><br/>
That's it !
<br/><br/><br/><br/>
<strong>Warning!</strong><br/>
<strong>do not run</strong> <code>python manage.py migrate</code> command on <strong>step 1</strong> (only makemigrations
命令)

注意
迁移文件是在我的本地系统中生成的,以重现该行为。它可能对您有所不同

关于python - 编写一个 Django 迁移,添加一个基于另一个字段的唯一字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51072426/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com