różnicowanie null = True, puste = True w django


901

Kiedy dodajemy pole bazy danych w django, zwykle piszemy:

models.CharField(max_length=100, null=True, blank=True)

To samo odbywa się ForeignKey, DecimalFielditd. Jaka jest podstawowa różnica w konieczności

  1. null=True tylko
  2. blank=True tylko
  3. null=True, blank=True

w odniesieniu do różnych ( CharField, ForeignKey, ManyToManyField, DateTimeField) pól. Jakie są zalety / wady korzystania z 1/2/3?




Tak, mam również ten przypadek użycia ForeignKeyz blank=True, ale bez null=True. Po zapisaniu modelu chcę automatycznie „opublikować” go, tworząc z niego opublikowany wpis. Nie mogę więc zapisywać nullw bazie danych, ponieważ każdy model musi być „opublikowany”, ale chcę mieć możliwość pozostawienia pola pustego w panelu administratora.
osa

Myślę, że może Cię zainteresować [Zapisz puste, zerowalne CharField jako null zamiast jako pusty ciąg] ( code.djangoproject.com/ticket/4136 ). Jest wiele dyskusji na ten temat i bardzo praktyczny problem, który możesz napotkać (np. Chcesz dodać adres URL openid dla każdego użytkownika, który może mieć wartość NULL i powinien być unikalny).
ramwin,

Odpowiedzi:


1081

null=Trueustawia NULL(kontra NOT NULL) na kolumnie w twojej bazie danych. Puste wartości dla typów pól Django, takich jak DateTimeFieldlub, ForeignKeybędą przechowywane jak NULLw DB.

blankokreśla, czy pole będzie wymagane w formularzach. Obejmuje to administratora i formularze niestandardowe. Jeśli blank=Trueto pole nie będzie wymagane, a jeśli tak, Falseto pole nie może być puste.

Kombinacja tych dwóch elementów jest tak częsta, ponieważ zazwyczaj jeśli pozwolisz, aby pole było puste w formularzu, będziesz potrzebować bazy danych, aby zezwolić na NULLwartości dla tego pola. Wyjątkiem są CharFieldsi i TextFields, które w Django nigdy nie są zapisywane jako NULL. Puste wartości są przechowywane w bazie danych jako pusty ciąg ( '').

Kilka przykładów:

models.DateTimeField(blank=True) # raises IntegrityError if blank

models.DateTimeField(null=True) # NULL allowed, but must be filled out in a form

Oczywiście te dwie opcje nie mają logicznego sensu (chociaż może istnieć przypadek użycia, null=True, blank=Falsejeśli chcesz, aby pole zawsze było wymagane w formularzach, opcjonalne, gdy zajmujesz się obiektem przez coś takiego jak powłoka).

models.CharField(blank=True) # No problem, blank is stored as ''

models.CharField(null=True) # NULL allowed, but will never be set as NULL

CHARi TEXTtypy nigdy nie są zapisywane jak NULLprzez Django, więc nie null=Truejest konieczne. Możesz jednak ręcznie ustawić jedno z tych pól, Noneaby wymusić ustawienie go jako NULL. Jeśli masz scenariusz, w którym może to być konieczne, nadal powinieneś dołączyć null=True.


8
IntegrityErrorjest wywoływany, gdy Django próbuje zapisać rekord w bazie danych. To pole nie musi być wypełnione przez użytkownika, i to jest problem, ponieważ na poziomie bazy danych nie ma wartości null.
Chris Pratt,

5
Nie, Chris próbuje wyjaśnić, dlaczego posiadanie wartości blank = True bez wartości null = True spowodowałoby problemy w obiekcie DateTimeField.
Vinod Kurup

4
UWAGA dla użytkowników Oracle: Nie jest prawdą, że „ CHARi TEXTNIGDY nie są zapisywane NULLprzez Django”. Jest to prawdą w przypadku większości backendów, ale Oracle wymusi pusty ciąg znaków na NULL, więc backend Django Oracle jest wyjątkiem od powyższej instrukcji Django Docs
stv

10
@ChrisPratt Drobne poprawki do twojego postu: CharFields można zapisać jako NULL w bazie danych (tłumacząc na NonePython), jeśli ustawisz null = True. W docs nawet powiedzieć, aby uniknąć ustawiania NULL = true, ponieważ pozwala to dwa różne rodzaje „Blanky” wartości. Właśnie przetestowałem to zachowanie z Django 1.8 / MySQL 5.6
Edward D'Souza

3
nikt nie zamierza wymienić kombinację: blank=True, null=False, default="something"?
Brian H.

124

W ten sposób mapy ORM blanki nullpola dla Django 1.8

class Test(models.Model):
    charNull        = models.CharField(max_length=10, null=True)
    charBlank       = models.CharField(max_length=10, blank=True)
    charNullBlank   = models.CharField(max_length=10, null=True, blank=True)

    intNull         = models.IntegerField(null=True)
    intBlank        = models.IntegerField(blank=True)
    intNullBlank    = models.IntegerField(null=True, blank=True)

    dateNull        = models.DateTimeField(null=True)
    dateBlank       = models.DateTimeField(blank=True)
    dateNullBlank   = models.DateTimeField(null=True, blank=True)        

Pola bazy danych utworzone dla PostgreSQL 9.4 to:

CREATE TABLE Test (
  id              serial                    NOT NULL,

  "charNull"      character varying(10),
  "charBlank"     character varying(10)     NOT NULL,
  "charNullBlank" character varying(10),

  "intNull"       integer,
  "intBlank"      integer                   NOT NULL,
  "intNullBlank"  integer,

  "dateNull"      timestamp with time zone,
  "dateBlank"     timestamp with time zone  NOT NULL,
  "dateNullBlank" timestamp with time zone,
  CONSTRAINT Test_pkey PRIMARY KEY (id)
)

Pola bazy danych utworzone dla MySQL 5.6 to:

CREATE TABLE Test (
     `id`            INT(11)     NOT  NULL    AUTO_INCREMENT,

     `charNull`      VARCHAR(10) NULL DEFAULT NULL,
     `charBlank`     VARCHAR(10) NOT  NULL,
     `charNullBlank` VARCHAR(10) NULL DEFAULT NULL,

     `intNull`       INT(11)     NULL DEFAULT NULL,
     `intBlank`      INT(11)     NOT  NULL,
     `intNullBlank`  INT(11)     NULL DEFAULT NULL,

     `dateNull`      DATETIME    NULL DEFAULT NULL,
     `dateBlank`     DATETIME    NOT  NULL,
     `dateNullBlank` DATETIME    NULL DEFAULT NULL
)

41
Innymi słowy, blanknie ma wpływu na bazę danych i nullkontroluje, czy kolumna bazy danych dopuszcza NULLwartości. Ta odpowiedź to naprawdę długa droga do powiedzenia tego i nie zawiera żadnych użytecznych informacji na temat blank.
Carl Meyer,

19
@CarlMeyer: Chciałem zobaczyć, jak to będzie mapowane do bazy danych i udostępniane, ponieważ zaoszczędziłoby to czas, aby inni zrobili to samo. Teoria kontra przykład robi różnicę, jeśli chodzi o asymilację i zaangażowanie w pamięć. W rzeczywistości starałem się dodać mapowanie dla bazy danych, której nie używałem. Dzięki za recenzję. Liczba osób, które uznały to za przydatne, oczywiście się z tobą nie zgadza.
użytkownik

5
Może to być przydatna odpowiedź, jeśli wyciągniesz wnioski podsumowujące z przedstawionych danych, ale nie sądzę, aby przedstawienie zrzutu danych surowych było przydatną odpowiedzią. W tym przypadku jest to rzeczywiście mylące odpowiedź, ponieważ (bez dalszego komentarza) oznacza to, że wpływ zarówno blanki nullpowinno być odzwierciedlone w kolumnach bazy danych, podczas gdy w rzeczywistości blankdotyczy tylko obsługę Pythona, a nie kolumn bazy danych. Inni mogą głosować, jeśli uznają to za przydatne; ludzie wprowadzani w błąd przez mylącą odpowiedź mogą również uważać ją za przydatną.
Carl Meyer,

4
Przyjęta odpowiedź, która ma prawie 3 lata, wyjaśnia wszystko szczegółowo. Nie ma sensu powtarzać tutaj tych samych informacji.
użytkownik

48

Jak powiedziano w Django Model Odniesienie do pola: Link

Opcje pól

Następujące argumenty są dostępne dla wszystkich typów pól. Wszystkie są opcjonalne.


null

Field.null

Jeśli TrueDjango zapisze puste wartości jak NULLw bazie danych. Domyślnie jest False.

Unikaj używania nullpól opartych na ciągach, takich jak CharFieldi, TextFieldponieważ puste wartości ciągów zawsze będą przechowywane jako puste ciągi, a nie jako NULL. Jeśli pole oparte na łańcuchach ma null=True, oznacza to, że ma dwie możliwe wartości „brak danych”: NULLi pusty ciąg. W większości przypadków nadmiarowe jest posiadanie dwóch możliwych wartości „brak danych”; Konwencja Django polega na tym, aby nie używać pustego ciągu NULL .

W przypadku pól zarówno łańcuchowych, jak i nie łańcuchowych należy również ustawić, blank=Truejeśli chcesz zezwolić na puste wartości w formularzach, ponieważ nullparametr wpływa tylko na przechowywanie bazy danych (patrz blank).

Uwaga

Podczas korzystania z zaplecza bazy danych Oracle wartość NULL będzie przechowywana w celu oznaczenia pustego ciągu niezależnie od tego atrybutu


blank

Field.blank

Jeśli Truepole może być puste. Domyślnie jestFalse .

Zauważ, że to jest inne niż null. nulljest całkowicie związany z bazą danych, podczas gdy blankjest związany z walidacją. Jeśli pole ma blank=True, sprawdzanie poprawności formularza pozwoli na wprowadzenie pustej wartości. Jeśli pole ma blank=False, pole będzie wymagane.


46

Ważne jest, aby zrozumieć, że opcje w definicji pola modelu Django służą (co najmniej) dwóm celom: zdefiniowaniu tabel bazy danych oraz określeniu domyślnego formatu i sprawdzania poprawności formularzy modelu. (Mówię „domyślny”, ponieważ wartości można zawsze zastąpić, podając niestandardowy formularz). Niektóre opcje wpływają na bazę danych, niektóre opcje wpływają na formularze, a niektóre na oba.

Jeśli chodzi o nulli blank, inne odpowiedzi już wyjaśniły, że ta pierwsza wpływa na definicję tabeli bazy danych, a druga na sprawdzanie poprawności modelu. Myślę, że rozróżnienie można uczynić jeszcze jaśniejszym, patrząc na przypadki użycia dla wszystkich czterech możliwych konfiguracji:

  • null=False, blank=False: Jest to konfiguracja domyślna i oznacza, że ​​wartość jest wymagana we wszystkich okolicznościach.

  • null=True, blank=True: Oznacza to, że pole jest opcjonalne we wszystkich okolicznościach. (Jak zauważono poniżej, nie jest to jednak zalecany sposób, aby pola oparte na łańcuchach były opcjonalne).

  • null=False, blank=True: Oznacza to, że formularz nie wymaga wartości, ale baza danych tak. Istnieje wiele przypadków użycia tego:

    • Najczęstszym zastosowaniem są opcjonalne pola oparte na łańcuchach. Jak zauważono w dokumentacji , idiom Django ma używać pustego ciągu, aby wskazać brakującą wartość. Gdyby NULLbyło to również dozwolone, skończyłbyś na dwóch różnych sposobach wskazania brakującej wartości.

    • Inną częstą sytuacją jest to, że chcesz automatycznie obliczyć jedno pole na podstawie wartości innego ( save()powiedzmy w metodzie). Nie chcesz, aby użytkownik podał wartość w formularzu (stąd blank=True), ale chcesz, aby baza danych wymusiła, że ​​wartość jest zawsze podana ( null=False).

    • Innym zastosowaniem jest wskazanie, że a ManyToManyFieldjest opcjonalne. Ponieważ to pole jest zaimplementowane jako osobna tabela, a nie kolumna bazy danych, nulljest bez znaczenia . Wartość parametru blankbędzie nadal wpływać na formularze, kontrolując, czy sprawdzanie poprawności zakończy się powodzeniem, gdy nie będzie żadnych relacji.

  • null=True, blank=False: Oznacza to, że formularz wymaga wartości, ale baza danych nie. Może to być najczęściej używana konfiguracja, ale istnieją dla niej pewne przypadki użycia:

    • Całkowicie uzasadnione jest wymaganie od użytkowników, aby zawsze podawali wartość, nawet jeśli nie jest to wymagane przez logikę biznesową. W końcu formularze są tylko jednym sposobem dodawania i edytowania danych. Możliwe, że masz kod generujący dane, które nie wymagają takiej samej ścisłej weryfikacji, jakiej potrzebujesz od ludzkiego edytora.

    • Innym przypadkiem użycia, który widziałem, jest sytuacja, w ForeignKeyktórej nie chcesz zezwalać na usuwanie kaskadowe . Oznacza to, że w normalnym użyciu relacja powinna zawsze istnieć ( blank=False), ale jeśli rzecz, którą wskazuje, zostanie usunięta, nie chcesz, aby ten obiekt również został usunięty. W takim przypadku możesz użyć null=Truei on_delete=models.SET_NULLzaimplementować prosty rodzaj miękkiego usuwania .


1
To idealna odpowiedź, wszystkie możliwe kombinacje zostały wyjaśnione w bardzo zwięzły sposób!
Rus

1
Powinna być zaakceptowana odpowiedź.
Tom Mac

28

Być może masz odpowiedź, ale do dziś trudno jest ocenić, czy wartość null = True, czy blank = True, czy jedno i drugie w polu. Osobiście uważam, że zapewnianie tak wielu opcji programistom jest dość bezużyteczne i mylące. Pozwól obsłużyć wartości zerowe lub puste, jak chcą.

Śledzę tę tabelę z Two Scoops of Django :wprowadź opis zdjęcia tutaj

Tabela pokazująca, kiedy należy użyć wartości null lub pustej dla każdego typu pola


26

Po prostu null=Truedefiniuje, że baza danych powinna akceptować NULLwartości, z drugiej strony blank=Truedefiniuje przy sprawdzaniu poprawności formularza, to pole powinno akceptować puste wartości lub nie (Jeśli blank=Truezaakceptuje formularz bez wartości w tym polu i blank=False[wartość domyślna] przy sprawdzaniu poprawności formularza, pokaże to pole jest wymagane błąd.

null=True/False związane z bazą danych

blank=True/False związane z weryfikacją formularza


11

Oto przykład pola z blank= Trueinull=True

opis = modele. Pole tekstowe (puste = True, null = True)

W takim przypadku:: blank = Trueinformuje nasz formularz, że można pozostawić pole opisu puste

i

null = True: informuje naszą bazę danych, że można zapisać wartość zerową w naszym polu db i nie podawać błędu.


7

Oto główna różnica null=Truei blank=True:

Domyślna wartość obu nulli blankjest fałszywy. Obie wartości działają na poziomie pola, tj. Czy chcemy zachować pole, nullczy blank.

null=Trueustawi wartość pola na NULLnp. brak danych. Zasadniczo dotyczy to wartości kolumny baz danych.

date = models.DateTimeField(null=True)

blank=Trueokreśla, czy pole będzie wymagane w formularzach. Dotyczy to administratora i własnych formularzy niestandardowych.

title = models.CharField(blank=True) // title can be kept blank. W bazie danych ("")będą przechowywane. null=True blank=TrueOznacza to, że pole jest opcjonalne we wszystkich okolicznościach.

epic = models.ForeignKey(null=True, blank=True)
// The exception is CharFields() and TextFields(), which in Django are never saved as NULL. Blank values a

6
null = True

Oznacza to, że nie ma ograniczeń bazy danych dla pola do wypełnienia, więc możesz mieć obiekt o wartości null dla wypełnionego pola, który ma tę opcję.

blank = True

Oznacza, że ​​nie ma ograniczeń sprawdzania poprawności w formularzach django. więc po wypełnieniu formularza modelFormdla tego modelu możesz pozostawić pole z tą opcją niewypełnioną.


6

Domyślne wartości null i blank to False.

Null: Jest to związane z bazą danych. Określa, czy dana kolumna bazy danych przyjmuje wartości zerowe, czy nie.

Puste: Jest to związane z walidacją. Będzie używany podczas sprawdzania poprawności formularzy, podczas wywoływania form.is_valid ().

Biorąc to pod uwagę, doskonale jest mieć pole o wartości null = True i puste = False. Znaczenie na poziomie bazy danych pole może mieć wartość NULL, ale na poziomie aplikacji jest to pole wymagane.

Teraz, gdy większość programistów myli się: Definiowanie null = True dla pól opartych na ciągach znaków, takich jak CharField i TextField. Unikaj tego. W przeciwnym razie uzyskasz dwie możliwe wartości „brak danych”, to znaczy: Brak i pusty ciąg. Posiadanie dwóch możliwych wartości „brak danych” jest zbędne. Konwencja Django polega na użyciu pustego ciągu, a nie NULL.


5

Kiedy zapisujemy cokolwiek w Django admin, następuje weryfikacja dwóch kroków, na poziomie Django i na poziomie bazy danych. Nie możemy zapisać tekstu w polu liczbowym.

Baza danych ma typ danych NULL, to nic. Kiedy Django tworzy kolumny w bazie danych, określa, że ​​nie mogą być puste. A jeśli spróbujesz zapisać NULL, otrzymasz błąd bazy danych.

Również na poziomie Django-Admin wszystkie pola są domyślnie wymagane, nie można zapisać pustego pola, Django wyświetli błąd.

Tak więc, jeśli chcesz zapisać puste pole, musisz zezwolić na to na poziomie Django i bazy danych. blank = True - pozwoli na puste pole w panelu administracyjnym null = True - pozwoli na zapisanie NULL w kolumnie bazy danych.


5

Jest jeden punkt, w którym null=Truebyłby konieczny nawet na a CharFieldlub TextFieldwtedy, gdy baza danych ma uniqueustawioną flagę dla kolumny.

Innymi słowy, jeśli masz unikalny Char / TextField w Django, musisz użyć tego:

models.CharField(blank=True, null=True, unique=True)

W przypadku nieunikalnego CharField lub TextField, lepiej będzie pominąć, w null=Trueprzeciwnym razie niektóre pola zostaną ustawione jako NULL, a inne jako „”, i będziesz musiał za każdym razem sprawdzać wartość pola dla NULL.


3

null oznacza bazę danych, a puste pole służy do sprawdzania poprawności pól, które chcesz pokazać w interfejsie użytkownika, takim jak pole tekstowe, aby uzyskać nazwisko osoby. Jeśli nazwisko = models.charfield (puste = prawda), nie poprosiło użytkownika o podanie nazwiska, ponieważ jest to teraz pole opcjonalne. Jeśli nazwisko = models.charfield (null = true) , oznacza to, że jeśli to pole nie otrzyma żadnej wartości od użytkownika, to zapisze w bazie danych jako pusty ciąg „”.


1

Znaczenie null = True i blank = True w modelu zależy również od tego, jak te pola zostały zdefiniowane w klasie formularza.

Załóżmy, że zdefiniowałeś następującą klasę:

class Client (models.Model):
    name = models.CharField (max_length=100, blank=True)
    address = models.CharField (max_length=100, blank=False)

Jeśli klasa formularza została zdefiniowana w następujący sposób:

class ClientForm (ModelForm):
    class Meta:
        model = Client
        fields = ['name', 'address']
        widgets = {
            'name': forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
            'address': forms.TextInput (attrs = {'class': 'form-control form-control-sm'})
        }

Wówczas pole „nazwa” nie będzie obowiązkowe (ze względu na puste = True w modelu), a pole „adres” będzie obowiązkowe (z powodu pustego = False w modelu).

Jeśli jednak klasa ClientForm została zdefiniowana w następujący sposób:

class ClientForm (ModelForm):
    class Meta:
        model = Client
        fields = ['name', 'address']

    name = forms.CharField (
        widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
    )
    address = forms.CharField (
        widget = forms.TextInput (attrs = {'class': 'form-control form-control-sm'}),
    )

Następnie oba pola („nazwa” i „adres”) będą obowiązkowe, „ponieważ pola zdefiniowane deklaratywnie są pozostawione w niezmienionej postaci” ( https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/ ) , tzn. domyślnym atrybutem „wymagana” pola formularza jest Prawda, a to wymaga wypełnienia pól „nazwa” i „adres”, nawet jeśli w modelu pole zostało ustawione na puste = Prawda.



0

Poniższa tabela pokazuje główne różnice:

+--------------------------------------------------------------------+
| Purpose                  | null=True        | blank = True         |
|--------------------------|------------------|----------------------|
| Field can be empty in DB | Do this          | Unaffected           |
|--------------------------|------------------|----------------------|
| ModelForm(required field)| Unaffected       | field not required   |
|--------------------------|------------------|----------------------|
| Form Validation          | Unaffected       | field not required   |
|--------------------------|------------------|----------------------|
| on_delete=SET_NULL       | Need this        | Unaffected           |
+--------------------------------------------------------------------+

0

W bardzo prostych słowach ,

Puste jest inne niż null.

wartość null jest związana wyłącznie z bazą danych , natomiast wartość pusta dotyczy walidacji (wymagana w formie) .

Jeśli null=TrueDjango to zrobi store empty values as NULL in the database. Jeśli pole ma blank=True, sprawdzanie poprawności formularza będzie allow entry of an empty value. Jeśli pole ma puste pole = False, pole będzie wymagane.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.