ważne jest, aby rozwiązać ten problem na poziomie modelu, a nie na poziomie formularza, ponieważ dane może wchodzić przez API, przez skrypty importowe, z powłoki itp. Minusem ustawienia null=True
na CharField jest to, że kolumna może zakończyć się zarówno pustymi ciągami, jak i wartościami NULL, co jest nieco niejednoznaczne, ale generalnie nie stanowi problemu w moim doświadczeniu. Jeśli chcesz żyć z tą niejednoznacznością, oto jak to zrobić w kilku krokach:
1) Ustaw null=True, blank=True
na polu i przenieś zmiany.
2) masaż dane tak, że wszystkie istniejące puste struny są zmieniane na wartości null:
items = Foo.objects.all()
for item in items:
if not item.somefield:
item.somefield = None
item.save()
3) Dodaj niestandardową metodę save()
do modelu:
def save(self, *args, **kwargs):
# Empty strings are not unique, but we can save multiple NULLs
if not self.somefield:
self.somefield = None
super().save(*args, **kwargs) # Python3-style super()
4) Ustaw unique=True
na dziedzinie i migrować ją również.
Teraz możesz przechowywać somefield
jako pustą lub unikatową wartość, niezależnie od tego, czy używasz administratora, czy jakiejkolwiek innej metody wprowadzania danych.
Jeśli wolisz nie mieć kilka migracje, oto przykład jak to zrobić w jednym migracji:
from __future__ import unicode_literals
from django.db import migrations, models
def set_nulls(apps, schema_editor):
Event = apps.get_model("events", "Event")
events = Event.objects.all()
for e in events:
if not e.wdid:
e.wdid = None
e.save()
class Migration(migrations.Migration):
dependencies = [
('events', '0008_something'),
]
operations = [
migrations.AlterField(
model_name='event',
name='wdid',
field=models.CharField(blank=True, max_length=32, null=True),
),
migrations.RunPython(set_nulls),
migrations.AlterField(
model_name='event',
name='wdid',
field=models.CharField(blank=True, max_length=32, null=True, unique=True),
),
]
Usunąłem pole Twitter_id, a następnie ponownie je dodałem używając South.Teraz działa bez żadnych problemów. – noahandthewhale
Django traktuje puste pole jako pusty ciąg '''', a 'unique = True' nie zezwala na wiele wpisów z wartością' ''. Pozwoli to jednak na wielokrotne wpisy z 'twitter_id = None'. – Alasdair