如何在Django中向大文本字段添加唯一约束?

问题描述 投票:1回答:1

models.py:

class PageURL(models.Model):
    url = models.TextField(max_length=2048, unique=True)

迁移过程中的错误:

django.db.utils.OperationalError:(1170,使用了“ BLOB / TEXT列'url'在没有密钥长度的密钥规范中”)

我考虑了一个CharField,但Django表示此用例的最大值为255个字符。最初,我只有TextField(unique=True),但决定添加一个max_length,我通常听说该URL的长度为2048,但这无助于使错误静音。

我尝试了没有max_length且只有唯一约束集的CharField。

core.PageURL.url:(fields.E120)CharFields必须定义一个'max_length'属性。 core.PageURL.url:(mysql.E001)MySQL不允许唯一CharFields的max_length> 255。

我操纵的解决方案是进入phpMyAdmin,并手动将结构更改为varchar(2048),并为其添加唯一约束。

mysql django mysql-python
1个回答
1
投票

MySQL BLOB/TEXT列不可能有唯一的约束。有关详细说明,请参见this问题。

要解决您所在的迁移锁定,您需要先将迁移回滚到该点,然后再尝试向unique=True字段添加url约束。浏览myapp/migrations以了解该模型,并确定何时准确。该文件应如下所示:

class Migration(migrations.Migration):

    dependencies = [
        (<myapp>, <migration name>),
    ]

    operations = [
        migrations.AlterField(
            model_name='PageURL',
            name='url',
            field=models.TextField(max_length=2048, unique=True),
        ),
    ]

现在,从命令行运行python3 manage.py migrate <myapp> <migration name>

最后,删除<migration name>之后的所有迁移。

编辑

我认为我至少应该尝试为您的特定情况提供解决方案,尽管我不知道该模型的确切用途。

如果您想拥有唯一的url列,可以尝试这样的FK关系:

class Url(models.Model):
    protocol = models.CharField(max_length=10)
    sld = models.CharField(max_length=2048, unique=True)
    tld = models.CharField(max_length=10)

    class Meta:
        unique_together = (('protocol', 'sld', 'tld'),)

    def __str__(self):
        return f'{self.protocol}://{self.sld}.{self.tld}'

现在在任何需要url列的模型上,您都可以执行以下操作:

class SomeModel(models.Model):
    url = models.ForeignKey(Url, related_name='url_path', on_delete=models.PROTECT)
    url_path = models.CharField(max_length=255)

    def get_url(self):
        return f'{self.url}/{self.url_path}'
© www.soinside.com 2019 - 2024. All rights reserved.