2016-03-24 21 views
13

Django highly suggestskhông để sử dụng null=True cho các trường dựa trên chuỗi trường CharField và TextField để không có hai giá trị có thể cho "không có dữ liệu" (giả sử bạn cho phép các chuỗi rỗng có blank=True). Điều này hoàn toàn hợp lý với tôi và tôi làm điều này trong tất cả các dự án của tôi.Trong Django 1.9, quy ước sử dụng JSONField (native postgres jsonb) là gì?

Django 1.9 giới thiệu JSONField, sử dụng loại dữ liệu Postgres jsonb cơ bản. Đề xuất trên có được chuyển sang JSONField (ví dụ: blank=True nên được sử dụng thay vì null=True) không? Hoặc, nên sử dụng null=True thay thế? Hoặc, nên sử dụng default=dict thay thế? Hoặc là, ..? Tại sao?

Nói cách khác, quy ước cho JSONField gốc mới là gì, khi bạn muốn chỉ cho phép một giá trị "không có dữ liệu"? Hãy ủng hộ câu trả lời của bạn bởi vì tôi đã làm rất nhiều nghiên cứu và không thể tìm thấy bất cứ điều gì chính thức. Cảm ơn trước.

+3

sau khi đọc tài liệu, tôi sẽ đặt cược null = Đúng là tốt nhất, vì JSONField phải là đối tượng hợp lệ và thường là đối tượng "trống" bạn sử dụng phép gán rỗng để chỉ ra điều đó. chỉ 2c của tôi. –

Trả lời

18

Quy ước ngụ ý từ mã Django có vẻ là lưu trữ giá trị null null là NULL ngược với chuỗi rỗng (như quy ước cho CharField). Tôi nói điều này bởi vì những điều sau đây:

Các empty_strings_allowed được thừa hưởng từ Field trong CharField, và được thiết lập để True:

django/db/models/fields/__init__.py#L96

class Field(RegisterLookupMixin): 
    """Base class for all field types""" 

    # Designates whether empty strings fundamentally are allowed at the 
    # database level. 
    empty_strings_allowed = True 
    ... 

JSONField, tuy nhiên, ghi đè nó với False:

django/contrib/postgres/fields/jsonb.py#L13

class JSONField(Field): 
    empty_strings_allowed = False 
    ... 

Điều này gây CharField 's để mặc định ""JSONField' s để None khi bạn khởi tạo một mô hình mà không đi một cách rõ ràng các giá trị cho các lĩnh vực này.

django/db/models/fields/init.py#L791

def get_default(self): 
    """ 
    Returns the default value for this field. 
    """ 
    if self.has_default(): 
     if callable(self.default): 
      return self.default() 
     return self.default 
    if (not self.empty_strings_allowed or (self.null and 
       not connection.features.interprets_empty_strings_as_nulls)): 
     return None 
    return "" 

Do đó, nếu bạn muốn thực hiện một JSONField tùy chọn, bạn phải sử dụng:

json_field = JSONField(blank=True, null=True) 

Nếu bạn chỉ sử dụng blank=True, như bạn muốn cho CharField, bạn sẽ nhận được IntegrityError khi cố gắng chạy MyModel.objects.create(...) mà không vượt qua một đối số json_field một cách rõ ràng.

2

Chỉ muốn thêm rằng bạn nên tránh đặt giá trị mặc định trên JSONField. Tôi vừa mắc lỗi học sinh bằng cách đặt nó vào {}. Kết quả là các đối tượng mới sẽ nhận được giá trị của đối tượng cuối cùng nếu nó không được thiết lập rõ ràng. Một hành vi Python của nó vốn có trong JSONField, mà tôi quên xem xét.

+6

Bạn không cần phải tránh mặc định. Sự cố này xảy ra vì bạn đã cung cấp một đối tượng có thể thay đổi làm mặc định. Bạn nên cung cấp 'dict' có thể gọi thay vì' {} '.Kiểm tra [docs] (https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/#django.contrib.postgres.fields.JSONField): "Nếu bạn đặt trường này là mặc định, hãy đảm bảo nó là một callable như dict (cho một mặc định rỗng) hoặc một callable trả về một dict (như một hàm). Sử dụng default = {} tạo một default mặc định được chia sẻ giữa tất cả các instance của JSONField. " – Ariel

+0

Cảm ơn bạn! Điểm tốt. – Harel

Các vấn đề liên quan