[PYTHON] Django NullCharField

Wenn Sie einem nicht wesentlichen CharField eine eindeutige Einschränkung hinzufügen, tritt ein DuplicateError auf. Ich war ein wenig süchtig danach, ein Feld zu erstellen, das Null anstelle von leeren Zeichen speichert, wenn keine Eingabe erfolgt, also schrieb ich ein Memo.

Verarbeitung zum Zeitpunkt des Speicherns

Wenn in Django CharField und TextField als leer gespeichert werden, werden sie als leere Zeichen anstelle von Null gespeichert. Wenn IntegerField usw. leer ist, wird Null ordnungsgemäß gespeichert. Wenn Sie also die Quelle von Django überprüfen, was Sie tun Ich habe die folgende Methode in der IntegerField-Klasse gefunden.

    def get_prep_value(self, value):
        value = super(IntegerField, self).get_prep_value(value)
        if value is None:
            return None
        return int(value)

Dies ist wie eine Methode, die den Wert vor dem Speichern der Datenbank konvertiert. Wenn Sie also None zurückgeben, wenn das Zeichen leer ist, wird Null gespeichert.

class NullCharField(models.CharField):
    def get_preg_value(self, value):
        value = Super(NullCharField, self).get_preg_value(value)
        return value if value else None

Dies speichert vorerst Null, wenn keine Eingabe in Form usw. erfolgt.

Verarbeitung zum Zeitpunkt des Erwerbs

Wenn Sie den Administratorbildschirm in diesem Status öffnen, tritt TypeError auf. Exception Value: coercing to Unicode: need string or buffer, NoneType found Da gesagt wird, dass "Zeichenfolge oder Puffer übergeben", wenn es "Keine" ist, scheint die Verarbeitung zum Konvertieren in leere Zeichen erforderlich zu sein.

Ich dachte, ich sollte die to_string-Methode neu schreiben, aber es funktioniert nicht. Es scheint notwendig zu sein, django.db.models.SubfieldBase nach verschiedenen Untersuchungen an die Metaklasse zu übergeben. Der von der Datenbank erhaltene Wert wird von setattr eingegeben (siehe die Init-Methode der Modellklasse von django.db.models.base). Wenn Sie SubfieldBase an die Meta-Klasse übergeben, wird die to_python-Methode intern bei setattr aufgerufen.

Aus diesem Grund habe ich Meta angegeben und die Verarbeitung zum Zeitpunkt der Erfassung hinzugefügt.

from django.db import models
from django.utils import six

class NullCharField(six.with_metaclass(models.SubfieldBase, models.CharField)):
    def get_preg_value(self, value):
        value = super(NullCharField, self).get_preg_value(value)
        return value if value else None

    def to_python(self, value):
        value = super(NullCharField, self).to_python(value)
        return value if value is not None else u''

Überprüfen Sie die Antwort

Ich dachte, es könnte etwas sein, und als ich es nachschlug, war es bei Oscar normal. https://github.com/django-oscar/django-oscar/blob/master/src/oscar/models/fields/init.py

class NullCharField(six.with_metaclass(SubfieldBase, CharField)):
    """
    CharField that stores '' as None and returns None as ''
    Useful when using unique=True and forms. Implies null==blank==True.

    When a ModelForm with a CharField with null=True gets saved, the field will
    be set to '': https://code.djangoproject.com/ticket/9590
    This breaks usage with unique=True, as '' is considered equal to another
    field set to ''.
    """
    description = "CharField that stores '' as None and returns None as ''"

    def __init__(self, *args, **kwargs):
        if not kwargs.get('null', True) or not kwargs.get('blank', True):
            raise ImproperlyConfigured(
                "NullCharField implies null==blank==True")
        kwargs['null'] = kwargs['blank'] = True
        super(NullCharField, self).__init__(*args, **kwargs)

    def to_python(self, value):
        val = super(NullCharField, self).to_python(value)
        return val if val is not None else u''

    def get_prep_value(self, value):
        prepped = super(NullCharField, self).get_prep_value(value)
        return prepped if prepped != u"" else None

    def deconstruct(self):
        """
        deconstruct() is needed by Django's migration framework
        """
        name, path, args, kwargs = super(NullCharField, self).deconstruct()
        del kwargs['null']
        del kwargs['blank']
        return name, path, args, kwargs

Es war fast da. Ich habe die Null- und Leerzeichen mit init überprüft. Außerdem scheint es für die Migration notwendig zu sein, das Überschreiben zu dekonstruieren.

Recommended Posts

Django NullCharField
Django
Django-Update
Django Note 4
Django Memorandum
Django-Suche
Django Installation
Django Zusammenfassung
Django-Test
Django # 2 (Vorlage)
Django Note 5
Django zum Anfassen
Berühre Django
Django Zusammenfassung
Django Shoho
Django + Docker
Django Glossar
Django Installation
Django: Referenzen
Django Note 1
Django Note 3
Django Note 2
Django Memo
Django Umweltbau
Django ~ settings.py edition ~
Django Heroku Deploy 1
Django HTML Vorlage Teil 2
Django Anfrageformular 2
Django startete Teil 1
Django-Modell: ManyToManyField
Was ist Django? .. ..
Modell in Django
Django funktionsbasierte Ansicht
Python Django Tutorial (5)
Django Lernnotiz
Python Django Tutorial (2)
[Django] as_view () Notizen
Erste Django Challenge
Django Makemigarations schafft Superuser
Django verwandte Websites
Django Versionsprüfung
Django startete Teil 4
Internationalisierungsunterstützung mit Django 1.9
CentOS8 --Play --Django
CentOS8 --Installieren - Django
Django Tutorial Memo
[Django] Wiederholen Sie die Migration
Django Umweltbau
Python Django Tutorial (8)
Python Django Tutorial (6)
Grundeinstellung von Django
Starten Sie das Django Tutorial 1
Django HTML-Vorlage
Tipps für Django-Vorlagen
Django Girls-3 Workflow
Django-Projektbasislinie
Django Heroku Deploy 2
CRUD mit Django
Django Filter Zusammenfassung
Django + Docker-Befehl