2016-03-24 22 views
13

Django highly suggestsdeğil Charfield ve TextField için null=True kullanmak için "hayır veri" için iki muhtemel değere sahip vermemek için alanlar (eğer blank=True boş dizeleri izin verdiğinizden varsayarak) dize tabanlı. Bu bana tamamen mantıklı geliyor ve bunu tüm projelerimde yapıyorum.Django 1.9'da, JSONField (native postgres jsonb) kullanmanın kuralları nedir?

Django 1.9, temel oluşturan Postgres jsonb veri türünü kullanan JSONField ürününü tanıtmaktadır. Yukarıdaki öneri JSONField'a geçiyor mu (yani null=True yerine kullanılmalıdır)? Ya da bunun yerine null=True kullanılmalıdır? Ya da bunun yerine default=dict kullanılmalıdır? Ya da ..? Niye ya? Başka bir deyişle, yalnızca bir "veri yok" değerine izin vermek istediğinizde, yeni yerel JSONField için kural nedir? Lütfen cevabınızı destekleyin çünkü çok fazla araştırma yaptım ve resmi bir şey bulamadım. Şimdiden teşekkürler. Django kodundan ima

+3

Dokümanları okuduktan sonra, bahse girerim null = True en iyisidir, çünkü JSONField geçerli bir nesne olmalı ve tipik olarak "boş" nesnelerini belirtmek için boş atamalar kullanırsınız. sadece benim 2c. –

cevap

18

kongre (CharField için kongre olduğu gibi) boş bir dize olarak karşıt olarak NULL olarak mağaza boş JSON değerlerine gibi görünüyor. Çünkü aşağıdakilerden söylüyorum:

empty_strings_allowedCharField yılında Field devralınan ve True olarak ayarlanır:

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 Ancak False ile geçersiz kılar:

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

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

Bu açıkça bu alanların değerlerini geçmeden bir model örneğini zaman None için s '"" ve JSONField varsayılan olarak s' harfinin CharField neden olur. Eğer yapmak istiyorsanız, kullanmak zorunda

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

Bu nedenle, JSONField opsiyonel: Eğer CharField için olduğu gibi,

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

sadece blank=True kullanmak verseniz de MyModel.objects.create(...)'u bir json_field argümanını açıkça geçmeden çalıştırmaya çalışırken bir IntegrityError olsun.

2

Sadece JSONField üzerinde varsayılan değerler belirlemekten kaçınmanız gerektiğini eklemeyi istedim. Sadece {}'a ayarlayarak bir öğrenci hatası yaptım. Sonuç, açıkça ayarlanmamışsa yeni nesnelerin son nesnenin değerini alacağıdır. Göz önünde bulundurmayı unuttuğum JSONField'a özgü bir Python davranışı.

+6

Varsayılan değerlerden kaçınmanıza gerek yoktur. Bu sorun, değiştirilebilen bir nesneyi varsayılan olarak sağladığınız için oldu. "{}" Yerine kalıcılığı olan "dict" değerini vermelisiniz.[Docs] 'u (https://docs.djangoproject.com/en/1.10/ref/contrib/postgres/fields/#django.contrib.postgres.fields.JSONField) kontrol edin: "Eğer alanı varsayılan olarak verirseniz Dict (boş bir varsayılan için) veya bir dict (bir işlev gibi) döndüren bir çağrılabilir gibi bir callable (default) = default = {}}, JSONField'ın tüm örnekleri arasında paylaşılan bir değiştirilebilen varsayılan oluşturur. – Ariel

+0

Teşekkür ederiz! İyi bir nokta. – Harel