2010-06-23 19 views
124

मैं एक User वर्ग जो (अंत में) models.Model से विरासत परिभाषित किया है। मैं इस मॉडल के लिए परिभाषित सभी क्षेत्रों की एक सूची प्राप्त करना चाहता हूं। उदाहरण के लिए, phone_number = CharField(max_length=20)। असल में, मैं Field कक्षा से प्राप्त कुछ भी प्राप्त करना चाहता हूं।Django: मॉडल फ़ील्ड की सूची प्राप्त करें?

मैंने सोचा कि मैं inspect.getmembers(model) का लाभ उठाकर इन्हें पुनर्प्राप्त करने में सक्षम हूं, लेकिन जिस सूची में यह लौटाता है, उनमें से कोई भी फ़ील्ड नहीं है। ऐसा लगता है कि Django पहले ही कक्षा को पकड़ लिया है और अपने सभी जादू विशेषताओं को जोड़ा है और वास्तव में परिभाषित किया गया है कि क्या बाहर परिभाषित किया गया है। तो ... मैं इन क्षेत्रों को कैसे प्राप्त कर सकता हूं? उनके पास शायद अपने आंतरिक उद्देश्यों के लिए उन्हें पुनर्प्राप्त करने के लिए एक कार्य है?

+0

यह मदद कर सकता है में काम किया , भी https://pypi.python.org/pypi/django-inspect-mo डेल/0.5 – Paolo

+0

संभावित डुप्लिकेट [Django में मॉडल के फ़ील्ड प्राप्त करें] (http://stackoverflow.com/questions/3647805/get-models-fields-in-django) – markpasc

उत्तर

216

Django संस्करण 1.8 और बाद के लिए:

get_all_field_names() विधि deprecated starting from Django 1.8 and will be removed in 1.10 है।

उपरोक्त लिंक प्रलेखन पृष्ठ get_all_field_names() का एक पूर्ण पिछड़ा-संगत कार्यान्वयन प्रदान करता है, लेकिन अधिकांश प्रयोजनों के लिए [f.name for f in MyModel._meta.get_fields()] को ठीक काम करना चाहिए।

Django संस्करणों के लिए 1.8 से पहले:

model._meta.get_all_field_names() 

कि चाल करना चाहिए।

इसके लिए एक वास्तविक मॉडल उदाहरण की आवश्यकता है। यदि आप केवल इतना है django.db.models.Model का एक उपवर्ग है, तो आप myproject.myapp.models.MyModel._meta.get_all_field_names()

+9

ऑब्जेक्ट्स को भी उनके नामों की तरह नहीं था। ऐसा लगता है कि यह 'model._meta.fields' में उपलब्ध है, और उनके नाम' field.name' के साथ पुनर्प्राप्त करने योग्य हैं। मुझे उम्मीद है कि यह जानकारी पुनर्प्राप्त करने का यह सबसे स्थिर तरीका है :) – mpen

+2

पूरी तरह से सुनिश्चित नहीं है। अंडरस्कोर यह इंगित करता है कि यह एक आंतरिक एपीआई है, अगर डैंजो लोगों ने इसे 'django.db.models.Model' पर वास्तव में सार्वजनिक विधि कॉल के लिए प्रचारित किया तो अच्छा होगा। मैं इसमें खोदूँगा और देख सकता हूं कि मुझे क्या मिल सकता है – rossipedia

+2

मुझे लगता है कि इसे '_meta' विशेषता के माध्यम से करना एकमात्र तरीका है ... इसके अतिरिक्त कई लोगों के लिए' _meta.many_to_many' में देखें! –

47

बुलाना चाहिए मैं इस मॉडल काफी उपयोगी django में जोड़ने से खोजें:

for field, val in object: 
    print field, val 
+2

विदेशी के बारे में क्या? मुझे इस तरह की त्रुटियां हैं 'django.db.models.fields.related.RelatedObjectDoesNotExist: कस्टममोडेल में कोई custom_attribute नहीं है। – SAKrisT

+0

' विदेशीकी 'मेरे लिए ठीक काम करता है। हालांकि, चुपचाप सभी अपवादों को पकड़ना एक विरोधी पैटर्न है। 'AttributeError' को पकड़ने के लिए बहुत बेहतर है, या कम से कम लॉग इन करें कि कुछ अपवाद चुपचाप निगल लिया गया था। – Sardathrion

6

यह करता है:

def __iter__(self): 
    for field_name in self._meta.get_all_field_names(): 
     value = getattr(self, field_name, None) 
     yield (field_name, value) 

यह आपको अपना काम करने दिया चाल। मैं केवल Django 1.7 में इसका परीक्षण करता हूं।

your_fields = YourModel._meta.local_fields 
your_field_names = [f.name for f in your_fields] 

Model._meta.local_fields कई करने वाली कई क्षेत्रों शामिल नहीं है। आपको उन्हें Model._meta.local_many_to_many का उपयोग करना चाहिए।

42

get_all_related_fields() यहां उल्लिखित विधि deprecated in 1.8 है। अब से get_fields() पर।

>> from django.contrib.auth.models import User 
>> User._meta.get_fields() 
+0

अब यह स्वीकार्य उत्तर होना चाहिए। Terse, और बिंदु पर। –

+0

हां यह जवाब है। – neuronet

4

MyModel._meta.get_all_field_names() था कई संस्करण वापस पदावनत और Django 1.10 में हटा दिया।

from itertools import chain 

list(set(chain.from_iterable(
    (field.name, field.attname) if hasattr(field, 'attname') else (field.name,) 
    for field in MyModel._meta.get_fields() 
    # For complete backwards compatibility, you may want to exclude 
    # GenericForeignKey from the results. 
    if not (field.many_to_one and field.related_model is None) 
))) 
1

बस को जोड़ने के लिए, मैं स्वयं वस्तु का उपयोग कर रहा, यह मेरे लिए काम किया:

यहाँ पीछे की ओर संगत सुझाव from the docs है

[f.name for f in self.model._meta.get_fields()] 
2

यह स्पष्ट नहीं है कि क्या आप एक उदाहरण है वर्ग या वर्ग ही है और क्षेत्रों को पुनः प्राप्त करने की कोशिश कर रहा है, लेकिन किसी भी तरह की, एक में उपयोग करना निम्नलिखित कोड

पर विचार रुख

instance = User.objects.get(username="foo") 
instance.__dict__ # returns a dictionary with all fields and their values 
instance.__dict__.keys() # returns a dictionary with all fields 
list(instance.__dict__.keys()) # returns list with all fields 

एक वर्ग

User._meta.__dict__.get("fields") # returns the fields 

# to get the field names consider looping over the fields and calling __str__() 
for field in User._meta.__dict__.get("fields"): 
    field.__str__() # e.g. 'auth.User.id' 
1

का उपयोग कम से कम Django 1.9.9 साथ - संस्करण मैं वर्तमान में उपयोग कर रहा हूँ -, ध्यान दें कि .get_fields() वास्तव में भी एक के रूप में "समझता है" किसी भी विदेशी मॉडल क्षेत्र, जो समस्याग्रस्त हो सकता है। कहते हैं कि तुम है:

class Parent(models.Model): 
    id = UUIDField(primary_key=True) 

class Child(models.Model): 
    parent = models.ForeignKey(Parent) 

यह इस प्रकार है कि

>>> map(lambda field:field.name, Parent._model._meta.get_fields()) 
['id', 'child'] 

जबकि, के रूप में @Rockallite द्वारा दिखाए गए

>>> map(lambda field:field.name, Parent._model._meta.local_fields) 
['id'] 
2
def __iter__(self): 
    field_names = [f.name for f in self._meta.fields] 
    for field_name in field_names: 
     value = getattr(self, field_name, None) 
     yield (field_name, value) 

यह मेरे लिए django==1.11.8

संबंधित मुद्दे