无论如何使用mysql db后端在django中创建唯一的TextField?

时间:2015-10-19 09:57:12

标签: 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()
    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')]

当我运行migrate时,mysql会出现此错误:

  

1170,“密钥规范中使用了BLOB / TEXT列'问题'   没有密钥长度“

我发现此错误已经讨论here。但是,我无法使用 CharField带有小限制,因为我需要存储长文本 (直到10000 char或更多)。

sqlite3和postgresql可以做到这一点(我的意思是django没有抱怨 TEXT)的密钥规范。

我需要使用mysql的原因是因为我将部署它的服务器 django app只提供mysql,没有postgresql。

那么,无论如何我能做到这一点吗?

1 个答案:

答案 0 :(得分:2)

看起来这是一个django / mysql错误django blames MySql和" wontfix"它。他们的建议是将密钥从模型中移开,只需手动添加约束。巨大的黑客,但是,这可能是唯一的解决方案。但是,如果密钥超过1000个字节,则需要重新编译MySql。

  

最大密钥长度为1000个字节。这也可以通过更改源和重新编译来更改。对于长度大于250字节的密钥的情况,使用比默认的1024字节更大的密钥块大小。 From The Manual

我不建议这样做有几个原因,包括表演和围绕hackery。我建议您创建一个唯一的哈希字段,而不是重新编译。这将创建所有字段的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)