2011-02-08 10 views
7

Belirli bir nesne için varolan tüm model alanlarının ve özelliklerinin bir listesini almaya çalışıyorum. Bir nesneyi tanımak için temiz bir yol var mı, böylece bir alan ve özelliklerden bahsedebilirim.Django'daki özellikleri ve model alanlarını nasıl inceleyebilirim?

{ 
    'id' : 1, 
    'url':'http://foo', 
    'location' : 'http://foo/jobs/1' 
} 

manken alan almak için model._meta.fields kullanabilirsiniz, ancak bu bana özellikleri olan şeyleri vermez ama:

class MyModel(Model) 
    url = models.TextField() 

    def _get_location(self): 
     return "%s/jobs/%d"%(url, self.id) 

    location = property(_get_location) 

İstediğim şöyle bir dicti döndüren bir şeydir gerçek DB alanları değil.

cevap

8

sonra sadece modeli alanlar ve özellikler (bu ilan kullanarak mülkiyet):

 
def get_fields_and_properties(model, instance): 
    field_names = [f.name for f in model._meta.fields] 
    property_names = [name for name in dir(model) if isinstance(getattr(model, name), property)] 
    return dict((name, getattr(instance, name) for name in field_names + property_names) 

instance = MyModel() 
print get_fields_and_properties(MyModel, instance) 

burada fazladan olan tek bitlik özelliğine karşılık alanları bulmak için sınıfa aracılığıyla çalışıyor tanımlayıcıları. Bunlara sınıf aracılığıyla erişme, tanımlayıcıyı verirken, örnek üzerinden size değerleri verir.

+0

Teşekkürler - bu tam olarak ihtiyacım olan şey. Örnekte "mülk" türlerini aramaya çalışıyordum, ama onları Sınıfta aramalıydım. – shreddd

0

Örneğinizde dir() işlevini kullanmalısınız. Ne olursa olsun '__' ile başlar ve örneğinizden değer almak için getattr'ı kullanın.

properties = [prop for prop in dir(SomeClass) if not prop.startswith("__")] 

obj = {} 
for prop in properties: 
    obj[prop] = getattr(myinstance, prop) 
+0

Django modelleri için pek işe yaramıyor. Nesneye (Django Model sınıfından miras alınan) yönelik çok sayıda başka yöntem ve değişken vardır, ancak kesinlikle Django alanları veya özellikleri değildir. Özellikler/alanlar ve diğer şeyler arasında ayrım yapabilmem gerekir. – shreddd

+0

Açıklığa kavuşturmak için - "mülkiyet" yerleşkesine atıfta bulunmaktayım (http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/) - sadece bir pythonun genel niteliği değil nesne. – shreddd

+0

@shreddd: db alanları ve özellikleri arasında ayrım yapmak için model._meta.fields ile olanı karşılaştırın. –

1

Sorun, sadece alanları istediğini söylüyorsun ama sonra karışımı içine özelliklerini atarak işleri karıştırır olduğunu. Python'da bir mülk ile herhangi bir rastgele yöntem arasında ayrım yapmak için herhangi bir kolay yol yoktur. Bu Django ile ilgili bir şey değil: bir özellik sadece bir tanımlayıcı yoluyla erişilen bir yöntemdir. Sınıftaki herhangi bir sayıda şey de tanımlayıcılar olacağından, aralarında ayrım yapmakta güçlük çekersiniz.

Sınıf düzeyinde, istediğiniz tüm özellikleri içeren bir liste tanımlayamamanızın bir nedeni var mı, o zaman öğelerin her birine yalnızca getattr numaralı telefonu arayın.

0
class Awesome(models.Model): 
foo = models.TextField() 
bar = models.CharField(max_length = 200) 

awe = Awesome() 
for property in awe.__dict__.copy(): 
# pass private properties. 
if not property.startswith('_'): 
    print property,getattr(awe,property) 

Django'da bunu nasıl yapıyorlar? Eğer sıkı istiyorsanız

+1

Bu, bana, dict içindeki her şeyi alır, ancak property() kullanılarak bildirilen şeyler değil. Görünüşe göre bu modeli doğrudan Model sınıfından çekmem gerekiyor. Yukarıdaki John Montgomery çözümüne bakınız. – shreddd