2011-02-08 26 views
7

Tôi đang cố gắng lấy danh sách tất cả các trường và thuộc tính mô hình hiện có cho một đối tượng cụ thể. Có một cách sạch để instrospect một đối tượng để tôi có thể nhận được một dict của các lĩnh vực và tài sản.Làm thế nào tôi có thể nhìn vào các thuộc tính và các trường mô hình trong Django?

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

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

    location = property(_get_location) 

Những gì tôi muốn là cái gì đó trả về một dict trông như thế này:

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

tôi có thể sử dụng model._meta.fields để có được những lĩnh vực người mẫu, nhưng điều này không cung cấp cho tôi những điều mà là tài sản nhưng không phải là trường DB thực.

Trả lời

8

Nếu bạn nghiêm túc muốn chỉ các lĩnh vực người mẫu và tài sản (số liệu kê khai sử dụng tài sản) thì:

 
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) 

Các bit chỉ đó là thêm ở đây đang chạy qua lớp để tìm các lĩnh vực tương ứng với tài sản mô tả. Truy cập chúng thông qua lớp cung cấp cho bộ mô tả, trong khi thông qua cá thể nó cung cấp cho bạn các giá trị.

+0

Cảm ơn - đây chính xác là những gì tôi cần. Tôi đã cố gắng tìm kiếm những thứ thuộc loại "tài sản" bên trong thể hiện, nhưng tôi nên đã tìm kiếm chúng trong lớp. – shreddd

0

Bạn nên sử dụng hàm dir() trên cá thể của bạn. Bỏ qua bất kỳ điều gì bắt đầu bằng '__' và sử dụng getattr để lấy giá trị từ cá thể của bạn.

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

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

Không hoàn toàn phù hợp với mô hình Django. Có rất nhiều phương pháp khác và các biến có sẵn cho đối tượng (kế thừa từ lớp mô hình Django cơ sở) nhưng không đúng lĩnh vực hoặc thuộc tính Django. Tôi cần để có thể phân biệt giữa các thuộc tính/lĩnh vực và các công cụ khác. – shreddd

+0

Để làm rõ - Tôi đang đề cập đến nội dung "thuộc tính" (http://adam.gomaa.us/blog/2008/aug/11/the-python-property-builtin/) - không chỉ là thuộc tính chung của một con trăn vật. – shreddd

+0

@shreddd: So sánh những gì bạn có với model._meta.fields để phân biệt giữa các trường và thuộc tính db. –

1

Vấn đề là bạn nói bạn chỉ muốn trường, nhưng sau đó làm phức tạp mọi thứ bằng cách ném thuộc tính vào danh sách kết hợp. Không có cách nào dễ dàng trong Python phân biệt giữa một thuộc tính và bất kỳ phương thức ngẫu nhiên nào khác. Đây không phải là bất cứ điều gì để làm với Django: nó chỉ đơn giản là một tài sản chỉ là một phương pháp được truy cập thông qua một bộ mô tả. Vì mọi thứ trong lớp cũng sẽ là bộ mô tả, bạn sẽ gặp khó khăn trong việc phân biệt giữa chúng.

Có lý do nào khiến bạn không thể xác định danh sách ở cấp lớp chứa tất cả các thuộc tính bạn muốn, sau đó chỉ cần gọi getattr trên từng yếu tố?

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) 

Đây là cách họ làm điều đó ở Django.

+1

Điều này cho tôi tất cả mọi thứ bên trong dict, nhưng không phải những thứ được khai báo sử dụng property(). Có vẻ như tôi cần phải kéo và kéo nó trực tiếp từ lớp Model. Xem giải pháp của John Montgomery ở trên. – shreddd

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