phân biệt null = True, blank = True trong django


903

Khi chúng ta thêm một trường cơ sở dữ liệu trong django, chúng ta thường viết:

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

Điều tương tự cũng được thực hiện ForeignKey, DecimalFieldv.v ... Sự khác biệt cơ bản trong việc có là gì

  1. null=True chỉ có
  2. blank=True chỉ có
  3. null=True, blank=True

đối với (khác nhau CharField, ForeignKey, ManyToManyField, DateTimeField) lĩnh vực. Những lợi thế / bất lợi của việc sử dụng 1/2/3 là gì?


8
Bạn có câu trả lời hay về điều đó tại đây: stackoverflow.com/questions/8159310/ và tại đây: stackoverflow.com/questions/4384098/
Kẻ


Vâng, tôi cũng có usecase này ForeignKeyvới blank=True, nhưng không có null=True. Khi mô hình được lưu, tôi muốn tự động "xuất bản" nó bằng cách tạo một mục được xuất bản từ nó. Vì vậy, tôi không thể lưu nullvào cơ sở dữ liệu, vì mọi mô hình phải được "xuất bản", nhưng tôi muốn có thể để trống trường trong quản trị viên.
osa

Tôi nghĩ rằng bạn có thể quan tâm đến [Lưu CharField trống, nullable dưới dạng null thay vì dưới dạng chuỗi rỗng] ( code.djangoproject.com/ticket/4136 ). Có nhiều cuộc thảo luận về vấn đề này và một vấn đề rất thực tế mà bạn có thể gặp phải (ví dụ: bạn muốn thêm một url mở cho mỗi người dùng có thể là null và phải là duy nhất).
ramwin

Câu trả lời:


1083

null=Trueđặt NULL(so với NOT NULL) trên cột trong DB của bạn. Các giá trị trống cho các loại trường Django như DateTimeFieldhoặc ForeignKeysẽ được lưu trữ như NULLtrong DB.

blankxác định xem trường sẽ được yêu cầu trong các hình thức. Điều này bao gồm quản trị viên và các hình thức tùy chỉnh của bạn. Nếu blank=Truesau đó, trường sẽ không được yêu cầu, trong khi nếu đó là Falsetrường không thể để trống.

Sự kết hợp của cả hai rất thường xuyên bởi vì thông thường nếu bạn cho phép một trường trống trong biểu mẫu của mình, bạn cũng sẽ cần cơ sở dữ liệu của mình để cho phép NULLcác giá trị cho trường đó. Ngoại lệ là CharFields và TextFields, trong Django không bao giờ được lưu dưới dạng NULL. Các giá trị trống được lưu trữ trong DB dưới dạng một chuỗi rỗng ( '').

Một vài ví dụ:

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

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

Rõ ràng, hai tùy chọn đó không có ý nghĩa logic để sử dụng (mặc dù có thể có trường hợp sử dụng null=True, blank=Falsenếu bạn muốn một trường luôn được yêu cầu trong các biểu mẫu, tùy chọn khi xử lý một đối tượng thông qua một cái gì đó như vỏ.)

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

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

CHARTEXTcác loại không bao giờ được lưu như NULLDjango, vì vậy null=Truekhông cần thiết. Tuy nhiên, bạn có thể đặt thủ công một trong các trường này Nonethành bắt buộc đặt nó thành NULL. Nếu bạn có một kịch bản có thể cần thiết, bạn vẫn nên đưa vào null=True.


8
IntegrityErrorđược nâng lên khi Django cố lưu bản ghi vào cơ sở dữ liệu. Trường không bắt buộc phải điền vào người dùng và đó là vấn đề vì ở cấp cơ sở dữ liệu, nó không phải là null.
Chris Pratt

5
Không, Chris đang cố gắng chỉ ra lý do tại sao có blank = True mà không có null = True sẽ gây ra sự cố trong DateTimeField.
Vinod Kurup

4
LƯU Ý cho người dùng Oracle: Không đúng " CHARTEXTKHÔNG BAO GIỜ được lưu như NULLDjango". Điều này đúng với hầu hết các phụ trợ, nhưng Oracle sẽ buộc một chuỗi trống vào NULL, vì vậy phụ trợ Django Oracle là một ngoại lệ đối với tuyên bố trên Django Docs
stv

10
@ChrisPratt Sửa lỗi nhỏ cho bài đăng của bạn: CharField có thể được lưu dưới dạng NULL trong cơ sở dữ liệu (dịch sang NonePython) nếu bạn đặt null = True. Các tài liệu thậm chí còn nói để tránh đặt null = True vì nó cho phép hai loại giá trị "trống" khác nhau. Tôi vừa thử nghiệm hành vi này với Django 1.8 / MySQL 5.6
Edward D'Souza

3
được ai sẽ đề cập đến sự kết hợp của: blank=True, null=False, default="something"?
Brian H.

124

Đây là cách các bản đồ blank& nulltrường ORM cho 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)        

Các trường cơ sở dữ liệu được tạo cho PostgreQuery 9.4 là:

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)
)

Các trường cơ sở dữ liệu được tạo cho MySQL 5.6 là:

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
Nói cách khác, blankkhông có tác dụng đối với cơ sở dữ liệu và nullkiểm soát xem cột cơ sở dữ liệu có cho phép NULLcác giá trị hay không. Câu trả lời này là một cách thực sự dài để nói điều đó và không cung cấp bất kỳ thông tin hữu ích nào blank.
Carl Meyer

19
@CarlMeyer: Tôi muốn xem nó sẽ ánh xạ tới cơ sở dữ liệu như thế nào và được chia sẻ vì nó sẽ tiết kiệm thời gian cho những người khác làm điều tương tự. Lý thuyết và ví dụ tạo ra sự khác biệt khi nói đến việc đồng hóa và cam kết với bộ nhớ. Trong thực tế, tôi đã tìm cách thêm ánh xạ cho cơ sở dữ liệu mà tôi không sử dụng. Cảm ơn các downvote. Số người tìm thấy điều này hữu ích rõ ràng không đồng ý với bạn.
người dùng

5
Nó có thể là một câu trả lời hữu ích nếu bạn rút ra một số kết luận tóm tắt từ dữ liệu được trình bày, nhưng tôi không nghĩ rằng việc trình bày một bãi chứa dữ liệu thô là một câu trả lời hữu ích. Trong trường hợp này, đây thực sự là một câu trả lời sai lệch, vì (không cần bình luận thêm) nó ngụ ý rằng tác động của cả hai blanknullnên được phản ánh trong các cột cơ sở dữ liệu, trong khi thực tế blankchỉ ảnh hưởng đến việc xử lý Python, chứ không phải các cột cơ sở dữ liệu. Những người khác được tự do upvote nếu họ thấy nó hữu ích; những người bị đánh lừa bởi một câu trả lời sai lầm cũng có thể nghĩ rằng nó hữu ích.
Carl Meyer

4
Câu trả lời được chấp nhận gần 3 tuổi giải thích mọi thứ một cách chi tiết. Không có điểm nào trong việc lặp lại thông tin tương tự ở đây.
người dùng

47

Như đã nói trong tài liệu tham khảo Trường mẫu Django: Liên kết

Tùy chọn trường

Các đối số sau đây có sẵn cho tất cả các loại trường. Tất cả là tùy chọn.


null

Field.null

Nếu True, Django sẽ lưu trữ các giá trị trống như NULLtrong cơ sở dữ liệu. Mặc định là False.

Tránh sử dụng nulltrên các trường dựa trên chuỗi như CharFieldTextFieldbởi vì các giá trị chuỗi trống sẽ luôn được lưu trữ dưới dạng chuỗi rỗng, không phải là NULL. Nếu một trường dựa trên chuỗi có null=True, điều đó có nghĩa là nó có hai giá trị có thể cho "không có dữ liệu": NULLvà chuỗi trống. Trong hầu hết các trường hợp, không có hai giá trị có thể có cho "không có dữ liệu"; quy ước Django là sử dụng chuỗi rỗng, không NULL.

Đối với cả các trường dựa trên chuỗi và không dựa trên chuỗi, bạn cũng sẽ cần đặt blank=Truenếu bạn muốn cho phép các giá trị trống trong các biểu mẫu, vì nulltham số chỉ ảnh hưởng đến lưu trữ cơ sở dữ liệu (xem blank).

Ghi chú

Khi sử dụng phụ trợ cơ sở dữ liệu Oracle, giá trị NULL sẽ được lưu trữ để biểu thị chuỗi trống bất kể thuộc tính này


blank

Field.blank

Nếu True, trường được phép để trống. Mặc định là False.

Lưu ý rằng điều này là khác nhau null. nullhoàn toàn liên quan đến cơ sở dữ liệu, trong khi blankliên quan đến xác nhận. Nếu một trường có blank=True, xác thực mẫu sẽ cho phép nhập một giá trị trống. Nếu một trường có blank=False, trường sẽ được yêu cầu.


46

Điều quan trọng là phải hiểu rằng các tùy chọn trong định nghĩa trường mô hình Django phục vụ (ít nhất) hai mục đích: xác định các bảng cơ sở dữ liệu và xác định định dạng mặc định và xác thực các biểu mẫu mô hình. (Tôi nói "mặc định" vì các giá trị luôn có thể bị ghi đè bằng cách cung cấp biểu mẫu tùy chỉnh.) Một số tùy chọn ảnh hưởng đến cơ sở dữ liệu, một số tùy chọn ảnh hưởng đến biểu mẫu và một số ảnh hưởng đến cả hai.

Khi nói đến nullblank, các câu trả lời khác đã làm rõ rằng cái trước ảnh hưởng đến định nghĩa bảng cơ sở dữ liệu và cái sau ảnh hưởng đến xác nhận mô hình. Tôi nghĩ rằng sự khác biệt có thể được làm rõ hơn nữa bằng cách xem xét các trường hợp sử dụng cho cả bốn cấu hình có thể:

  • null=False, blank=False: Đây là cấu hình mặc định và có nghĩa là giá trị được yêu cầu trong mọi trường hợp.

  • null=True, blank=True: Điều này có nghĩa là trường là tùy chọn trong mọi trường hợp. (Tuy nhiên, như đã lưu ý dưới đây, đây không phải là cách được đề xuất để làm cho các trường dựa trên chuỗi tùy chọn.)

  • null=False, blank=True: Điều này có nghĩa là biểu mẫu không yêu cầu giá trị nhưng cơ sở dữ liệu thì có. Có một số trường hợp sử dụng cho việc này:

    • Việc sử dụng phổ biến nhất là cho các trường dựa trên chuỗi tùy chọn. Như đã lưu ý trong tài liệu , thành ngữ Django là sử dụng chuỗi rỗng để biểu thị một giá trị còn thiếu. Nếu NULLcũng được cho phép, bạn sẽ kết thúc bằng hai cách khác nhau để chỉ ra một giá trị còn thiếu.

    • Một tình huống phổ biến khác là bạn muốn tự động tính toán một trường dựa trên giá trị của trường khác (theo save()phương pháp của bạn ). Bạn không muốn người dùng cung cấp giá trị dưới dạng (do đó blank=True), nhưng bạn muốn cơ sở dữ liệu thực thi rằng giá trị luôn được cung cấp ( null=False).

    • Một cách sử dụng khác là khi bạn muốn chỉ ra rằng a ManyToManyFieldlà tùy chọn. Bởi vì trường này được triển khai dưới dạng bảng riêng biệt thay vì cột cơ sở dữ liệu, nulllà vô nghĩa . Giá trị của blanký chí vẫn sẽ ảnh hưởng đến các hình thức, tuy nhiên, kiểm soát việc xác nhận có thành công hay không khi không có quan hệ.

  • null=True, blank=False: Điều này có nghĩa là biểu mẫu yêu cầu một giá trị nhưng cơ sở dữ liệu thì không. Đây có thể là cấu hình được sử dụng không thường xuyên nhất, nhưng có một số trường hợp sử dụng cho nó:

    • Hoàn toàn hợp lý khi yêu cầu người dùng của bạn luôn bao gồm một giá trị ngay cả khi logic kinh doanh của bạn không thực sự được yêu cầu. Rốt cuộc, các hình thức chỉ là một cách để thêm và chỉnh sửa dữ liệu. Bạn có thể có mã đang tạo dữ liệu không cần xác thực nghiêm ngặt mà bạn muốn yêu cầu trình soạn thảo của con người.

    • Một trường hợp sử dụng khác mà tôi đã thấy là khi bạn có một ForeignKeycái mà bạn không muốn cho phép xóa tầng . Đó là, trong sử dụng bình thường, mối quan hệ sẽ luôn luôn ở đó ( blank=False), nhưng nếu điều nó chỉ xảy ra sẽ bị xóa, bạn không muốn đối tượng này cũng bị xóa. Trong trường hợp đó, bạn có thể sử dụng null=Trueon_delete=models.SET_NULLthực hiện một loại xóa mềm đơn giản .


1
Đây là một câu trả lời hoàn hảo, tất cả các kết hợp có thể được giải thích một cách rất súc tích!
RusI

1
Nên là câu trả lời được chấp nhận.
Tom Mac

28

Tuy nhiên, bạn có thể có câu trả lời của mình cho đến ngày hôm nay, thật khó để đánh giá liệu nên đặt null = True hay blank = True hoặc cả hai vào một trường. Cá nhân tôi nghĩ rằng nó khá vô dụng và khó hiểu khi cung cấp nhiều tùy chọn cho các nhà phát triển. Hãy để xử lý các null hoặc khoảng trống theo cách họ muốn.

Tôi theo bảng này, từ Two Scoops of Django :nhập mô tả hình ảnh ở đây

Bảng hiển thị khi nào nên sử dụng null hoặc để trống cho từng loại trường


26

Đơn giản chỉ cần null=Truexác định cơ sở dữ liệu nên chấp nhận NULLcác giá trị, mặt khác blank=Trueđịnh nghĩa về xác thực mẫu, trường này có chấp nhận các giá trị trống hay không (Nếu blank=Truenó chấp nhận biểu mẫu không có giá trị trong trường đó và blank=False[giá trị mặc định] khi xác thực mẫu, nó sẽ hiển thị Trường này là lỗi bắt buộc .

null=True/False liên quan đến cơ sở dữ liệu

blank=True/False liên quan đến xác nhận mẫu


11

Dưới đây là một ví dụ về trường với blank= Truenull=True

description = model.TextField (blank = True, null = True)

Trong trường hợp này blank = True:: nói với biểu mẫu của chúng tôi rằng bạn có thể để trống trường mô tả

null = True: thông báo cho cơ sở dữ liệu của chúng tôi rằng việc ghi lại giá trị null trong trường db của chúng tôi là ổn và không đưa ra lỗi.


7
null = True

Có nghĩa là không có ràng buộc của cơ sở dữ liệu cho trường được điền, vì vậy bạn có thể có một đối tượng có giá trị null cho phần điền có tùy chọn này.

blank = True

Có nghĩa là không có ràng buộc xác nhận trong các hình thức django. vì vậy khi bạn điền vào một modelFormmô hình này, bạn có thể rời khỏi trường với tùy chọn này chưa được lấp đầy.


7

Đây là sự khác biệt chính của null=Trueblank=True:

Giá trị mặc định của cả hai nullblanklà Sai. Cả hai giá trị này đều hoạt động ở cấp trường tức là, cho dù chúng ta muốn giữ một trường nullhay blank.

null=Truesẽ đặt giá trị của trường thành NULLnghĩa là không có dữ liệu. Nó là cơ bản cho các giá trị cột cơ sở dữ liệu.

date = models.DateTimeField(null=True)

blank=Truexác định xem trường sẽ được yêu cầu trong các hình thức. Điều này bao gồm quản trị viên và các hình thức tùy chỉnh của riêng bạn.

title = models.CharField(blank=True) // title can be kept blank. Trong cơ sở dữ liệu ("")sẽ được lưu trữ. null=True blank=TrueĐiều này có nghĩa là lĩnh vực này là tùy chọn trong mọi trường hợp.

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

Các giá trị mặc định của null và trống là Sai.

Null: Nó liên quan đến cơ sở dữ liệu. Xác định nếu một cột cơ sở dữ liệu nhất định sẽ chấp nhận giá trị null hay không.

Trống: Nó liên quan đến xác nhận. Nó sẽ được sử dụng trong quá trình xác thực mẫu, khi gọi form.is_valid ().

Điều đó đang được nói, việc có một trường với null = True và blank = false là hoàn toàn ổn. Có nghĩa là ở cấp độ cơ sở dữ liệu, trường có thể là NULL, nhưng ở cấp ứng dụng, nó là trường bắt buộc.

Bây giờ, nơi hầu hết các nhà phát triển hiểu sai: Xác định null = True cho các trường dựa trên chuỗi như CharField và TextField. Tránh làm điều đó. Nếu không, cuối cùng bạn sẽ có hai giá trị có thể có cho dữ liệu không có dữ liệu, đó là: Không có và một chuỗi rỗng. Có hai giá trị có thể có cho không có dữ liệu. Quy ước Django là sử dụng chuỗi rỗng, không phải NULL.


5

Khi chúng tôi lưu bất cứ điều gì trong quản trị viên Django, hai bước xác thực xảy ra, ở cấp độ Django và ở cấp độ Cơ sở dữ liệu. Chúng tôi không thể lưu văn bản trong một trường số.

Cơ sở dữ liệu có kiểu dữ liệu NULL, không có gì. Khi Django tạo các cột trong cơ sở dữ liệu, nó chỉ định rằng chúng không thể để trống. Và nếu bạn cố lưu NULL, bạn sẽ gặp lỗi cơ sở dữ liệu.

Ngoài ra, ở cấp độ Django-Admin, tất cả các trường được yêu cầu theo mặc định, bạn không thể lưu trường trống, Django sẽ gây ra lỗi cho bạn.

Vì vậy, nếu bạn muốn lưu trường trống, bạn cần cho phép nó ở cấp độ Django và Cơ sở dữ liệu. blank = True - sẽ cho phép trường trống trong bảng quản trị null = True - sẽ cho phép lưu NULL vào cột cơ sở dữ liệu.


5

Có một điểm null=Truecần thiết ngay cả trên một CharFieldhoặc TextFieldvà đó là khi cơ sở dữ liệu uniqueđược đặt cờ cho cột.

Nói cách khác, nếu bạn đã có Char / TextField duy nhất trong Django, bạn sẽ cần sử dụng điều này:

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

Đối với CharField hoặc TextField không phải là duy nhất, tốt hơn hết bạn nên bỏ qua null=Truemột số trường khác sẽ được đặt là NULL trong khi các trường khác là "" và bạn sẽ phải kiểm tra giá trị trường cho NULL mọi lúc.


3

null là cho cơ sở dữ liệu và trống là để xác thực các trường mà bạn muốn hiển thị trên giao diện người dùng như trường văn bản để lấy tên cuối cùng của người đó. Nếu lastname = model.charfield (blank = true) thì không yêu cầu người dùng nhập họ vì đây là trường tùy chọn ngay bây giờ. Nếu lastname = model.charfield (null = true) thì có nghĩa là nếu trường này không nhận được bất kỳ giá trị nào từ người dùng thì nó sẽ lưu trữ trong cơ sở dữ liệu dưới dạng một chuỗi rỗng "".


1

Ý nghĩa của null = True và blank = True trong mô hình cũng phụ thuộc vào cách các trường này được định nghĩa trong lớp biểu mẫu.

Giả sử bạn đã định nghĩa lớp sau:

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

Nếu lớp biểu mẫu đã được định nghĩa như thế này:

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'})
        }

Sau đó, trường 'tên' sẽ không bắt buộc (do khoảng trống = Đúng trong mô hình) và trường 'địa chỉ' sẽ là bắt buộc (do khoảng trống = Sai trong mô hình).

Tuy nhiên, nếu lớp ClientForm đã được định nghĩa như thế này:

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'}),
    )

Sau đó, cả hai trường ('tên' và 'địa chỉ') sẽ là bắt buộc, "vì các trường được xác định khai báo được giữ nguyên trạng" ( https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/ ) , tức là mặc định cho thuộc tính 'bắt buộc' của trường biểu mẫu là True và điều này sẽ yêu cầu các trường 'tên' và 'địa chỉ' được điền, ngay cả khi, trong mô hình, trường đã được đặt thành blank = True.



0

Bảng này dưới đây cho thấy sự khác biệt chính:

+--------------------------------------------------------------------+
| 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

Nói một cách rất đơn giản ,

Trống khác với null.

rỗnghoàn toàn cơ sở dữ liệu liên quan đến , trong khi trống là xác nhận liên quan đến (bắt buộc theo mẫu) .

Nếu null=True, Django sẽ store empty values as NULL in the database. Nếu một lĩnh vực có blank=True, xác nhận mẫu sẽ allow entry of an empty value. Nếu một trường có khoảng trống = Sai, trường sẽ được yêu cầu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.