在django中是否有使用mysql db后端创建唯一文本字段的方法?

在django中是否有使用mysql db后端创建唯一文本字段的方法?,mysql,django,Mysql,Django,我为多项选择题创建了一个模型。每个问题有5个选择 一系列的答案。我需要每个问题对象都是唯一的,基于它的 问答。所以,我设计了这样的模型 from django.db import models class MultipleChoiceQuestion(models.Model): ANSWERS = [('a', 'a'), ('b', 'b'), ('c', 'c'), ('d', 'd'), ('e', 'e')] question = models.TextField(

我为多项选择题创建了一个模型。每个问题有5个选择 一系列的答案。我需要每个问题对象都是唯一的,基于它的 问答。所以,我设计了这样的模型

from django.db import models


class MultipleChoiceQuestion(models.Model):
    ANSWERS = [('a', 'a'), ('b', 'b'), ('c', 'c'), ('d', 'd'), ('e', 'e')]
    question = models.TextField()
    a = models.TextField()
    b = models.TextField()
    c = models.TextField()
    d = models.TextField()
    e = models.TextField()
    true_answer = models.CharField(max_length=1, choices=ANSWERS)

    class Meta:
        unique_together = [('question', 'a', 'b', 'c', 'd', 'e')]
当我运行迁移时,mysql会给出以下错误:

1170,“关键规范中使用的BLOB/TEXT列‘问题’” 没有键长度“

我发现这个错误已经被讨论过了。但是,我不能用
CharField
限制很小,因为我需要存储长文本 (直到10000字符或更多)

sqlite3和postgresql可以做到这一点(我的意思是django没有抱怨
文本
)的关键规范

我之所以需要使用mysql,是因为我将在其中部署mysql的服务器 django应用程序只提供mysql,没有postgresql


那么,我到底有没有办法做到这一点呢?

看起来这是一个django/mysql bug,在这里“wontfix”了它。他们的建议是不使用模型中的键,只需手动添加约束即可。巨大的黑客,但是的,这可能是唯一的解决方案。但是,如果密钥超过1000字节,则需要重新编译MySql

最大密钥长度为1000字节。这也可以通过更改源代码和重新编译来更改。对于长度超过250字节的密钥,将使用比默认值1024字节更大的密钥块大小

我不建议这样做,原因有几个,包括性能和所有黑客行为。我建议您创建一个唯一的散列字段,而不是重新编译。这将创建所有字段的md5和,并且始终为32个字符。重复的几率是1/2^128,所以你很安全

from django.db import models
import hashlib


class MultipleChoiceQuestion(models.Model):
    ANSWERS = [('a', 'a'), ('b', 'b'), ('c', 'c'), ('d', 'd'), ('e', 'e')]
    question = models.TextField()
    a = models.TextField()
    b = models.TextField()
    c = models.TextField()
    d = models.TextField()
    e = models.TextField()
    true_answer = models.CharField(max_length=1, choices=ANSWERS)
    unique_hash = models.CharField(max_length=32, unique=True)

    def save(self, *args, **kwargs):
        m = hashlib.md5()
        m.update(self.question)
        m.update(self.a)
        m.update(self.b)
        m.update(self.c)
        m.update(self.d)
        m.update(self.e)
        self.unique_hash = m.digest()
        super(MultipleChoiceQuestion, self).save(*args, **kwargs)

您可能希望使用
m.hexdigest()
as
m.digest()
将返回如下对象:
b'\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\t\x98\xec\xf8B~”
其中as
m.hexdigest()
将返回
d41d8cd98f00b204e98ecf842e