可选,但独特的SlugField

时间:2014-02-12 12:50:56

标签: django django-models

我需要SlugField这是可选的,如果不是空的,它应该是唯一的。

如果我使用django的SlugField,则允许空字符串,并且数据库中将有一个空字符串。但如果它是唯一的,则只允许使用空字符串的一行。

我的SlugField如果已设置,则应该是唯一的,如果未设置,则NoneNULL)应该是唯一的。

在数据库级别,它可以工作:唯一约束忽略NULL值。

由于我不想修改太多地方,因此数据库字段将是最佳解决方案。

1 个答案:

答案 0 :(得分:0)

这是我的解决方案:

from django.db.models import SlugField

# Inspired by: https://github.com/django-extensions/django-extensions/blob/master/django_extensions/db/fields/__init__.py

class SlugOrNullField(SlugField):
    """
    Don't insert empty slugs. If the slug is empty, insert NULL.

    Usecase: Unique, but optional slug. Unique constrains only applies
             to the values which are not NULL.
    """
    class MyModel(models.Model):
        slug = SlugField(null=True, unique=True, blank=True)
    """
    If you want to be really sure, that no empty slug is in your table, you can use this
    in a schema migration (south):
    """
    def forwards(self, orm):
        db.execute("ALTER TABLE myapp_foomodel add CONSTRAINT slug_not_empty CHECK (slug<>'')")
    """
    If you have a empty slug in your table, you can use this in a data migration:
    """
    def forwards(self, orm):
        db.execute("UPDATE myapp_foomodel SET slug=NULL WHERE slug='' ")



    def get_prep_value(self, value):
        value=value.strip()
        if not value:
            return None
        return value

    def get_internal_type(self):
        return "SlugField"

#South Plugin registrieren
from south.modelsinspector import add_introspection_rules
add_introspection_rules([], ["^djangotools\.dbfields\.SlugOrNullField"])