2013-01-22 23 views
8

Django modelinin örneklerine özel nitelikler eklemek istiyorum. Bu özellikler veritabanında saklanmamalıdır. Diğer herhangi bir sınıfta, özellikler sadece __init__ yöntemi ile başlatılabilir.Django modellerinde özel örnek özniteliklerine sahip olmanın doğru yolu nedir?

Bunu yapmak için üç farklı yol görebiliyorum ve bunların hiçbiri tamamen tatmin edici değil. Bunu yapmak için daha iyi/daha pythonic/djangoist bir yol olup olmadığını merak ediyorum?

  1. Override__init__ yöntemi: sözdizimi biraz dolambaçlı, ama çalışıyor.

    from django.db.models import Model 
    
    class Foo(Model): 
        def __init__(self, *args, **kwargs): 
        super(Model, self).__init__(*args, **kwargs) 
        self.bar = 1 
    
  2. Django post_init sinyali kullan: Bu çok okunabilir değil sınıf tanımının, dışında sınıf kodunu alır.
    from django.dispatch import receiver 
    from django.db.models.signals import post_init 
    @receiver(post_init, sender=Foo) 
        def user_init(sender, instance, *args, **kwargs): 
         instance.bar = 1 
    
  3. bir özelliğin yerine bir örnek yöntemini kullanın: Varsayılan davranış olarak yükseltilmiş bir genel istisna olan biraz rahatsız edici.
    class Foo(Model): 
        def bar(self): 
        try: 
         return self.bar 
        except: 
         self.bar = 1 
        return self.bar 
    
  4. bu üç seçenek Of

bana kötü az gibi ilk görünüyor. Ne düşünüyorsun? Herhangi bir alternatif?

cevap

3

geçersiz kılma depolanmış olan __init__ doğru yoldur.

7

Ben

class Foo(Model): 
    @property 
    def bar(self): 
     if not hasattr(self, '_bar'): 
      self._bar = 1 

     return self._bar 

Sonra bir fonksiyonu çağıran sadece bir özellik gibi yerine erişebilir piton mevcut mülkiyet dekoratör kullanırsınız()

Hatta daha basittir biraz alabilir yerleşik Yedek özelliği sağlayarak bu, yerine

class Foo(Model): 
    @property 
    def bar(self): 
     return getattr(self, '_bar', 1) 
+0

İlginç, @property dekoratör hakkında bilmiyordum. Ama sence bu çok çirkin değil mi? –

+0

Kodunuzdaki her yerde getattr belirtmek yerine yerleşik bir varsayılan değere sahip olmak istemezsiniz. Bu, python'da erişim yöntemleri oluşturmanın standart bir yoludur, bu yüzden çirkin olsaydık, sadece Guido'ya v3 için bir iyileştirme olarak gelmemiz gerekir: -P – Bryan

+1

Sadece birkaç yıl daha Python ile bu soruya geri döndüm kemerimin altında (2013! Genç ve masumdum ...). Bence bugün senin cevabınla giderim. '@ Özelliği' yaklaşım oldukça pythonic. Diğer yandan django model kurucuları nadiren geçersizdir. –

İlgili konular