জাঙ্গো: মডেল ক্ষেত্রের তালিকা পাবেন?


196

আমি একটি Userশ্রেণি সংজ্ঞায়িত করেছি যা (শেষ পর্যন্ত) এর উত্তরাধিকার সূত্রে প্রাপ্ত models.Model। আমি এই মডেলের জন্য সংজ্ঞায়িত সমস্ত ক্ষেত্রের একটি তালিকা পেতে চাই। উদাহরণস্বরূপ phone_number = CharField(max_length=20),। মূলত, আমি Fieldক্লাস থেকে উত্তরাধিকারসূত্রে প্রাপ্ত যে কোনও কিছুই পুনরুদ্ধার করতে চাই ।

আমি ভেবেছিলাম আমি সুবিধা গ্রহণ করে এগুলি পুনরুদ্ধার করতে সক্ষম হব inspect.getmembers(model), তবে যে তালিকাটি এটি প্রত্যাবর্তন করবে সেগুলির মধ্যে এই ক্ষেত্রগুলির কোনওটি নেই। দেখে মনে হচ্ছে জাজানো ইতিমধ্যে ক্লাসটি ধরে ফেলেছে এবং এর সমস্ত যাদু বৈশিষ্ট্য যুক্ত করেছে এবং আসলে কী সংজ্ঞায়িত হয়েছে তা ছড়িয়ে দিয়েছে। তাহলে ... আমি এই ক্ষেত্রগুলি কীভাবে পেতে পারি? তাদের নিজস্ব অভ্যন্তরীণ উদ্দেশ্যে তাদের পুনরুদ্ধার করার জন্য সম্ভবত কোনও ফাংশন আছে?


এটি খুব সাহায্য করতে পারে pypi.python.org/pypi/django-inspect-model/0.5
পাওলো

উত্তর:


46

বেশিরভাগ উত্তর পুরানো হিসাবে আমি আপনাকে জ্যাঙ্গো ২.২ এ আপডেট করার চেষ্টা করব এখানে পোস্টগুলি- আপনার অ্যাপ (পোস্ট, ব্লগ, দোকান, ইত্যাদি)

1) মডেল লিঙ্ক থেকে : https://docs.djangoproject.com/en/2.2/ref/models/meta/

from posts.model import BlogPost

all_fields = BlogPost._meta.fields
#or
all_fields = BlogPost._meta.get_fields()

মনে রাখবেন যে:

all_fields=BlogPost._meta.get_fields()

কিছু সম্পর্কও পাবে, যা প্রাক্তন। আপনি একটি দর্শন প্রদর্শন করতে পারবেন না।
আমার ক্ষেত্রে যেমন:

Organisation._meta.fields
(<django.db.models.fields.AutoField: id>, <django.db.models.fields.DateField: created>...

এবং

Organisation._meta.get_fields()
(<ManyToOneRel: crm.activity>, <django.db.models.fields.AutoField: id>, <django.db.models.fields.DateField: created>...

2) উদাহরণ থেকে

from posts.model import BlogPost

bp = BlogPost()
all_fields = bp._meta.fields

3) পিতামাতা মডেল থেকে

ধরা যাক আমাদের প্যারেন্ট মডেল হিসাবে পোস্ট রয়েছে এবং আপনি তালিকার সমস্ত ক্ষেত্র দেখতে চান এবং পিতামাতার ক্ষেত্রগুলি কেবল সম্পাদনা মোডে পড়তে হবে।

from django.contrib import admin
from posts.model import BlogPost 




@admin.register(BlogPost)
class BlogPost(admin.ModelAdmin):
    all_fields = [f.name for f Organisation._meta.fields]
    parent_fields = BlogPost.get_deferred_fields(BlogPost)

    list_display = all_fields
    read_only = parent_fields

1
আমি এটি সঠিক বলে ধরে নেব এবং এটিকে নতুন উত্তর হিসাবে গ্রহণ করব। আপডেটের জন্য ধন্যবাদ!
এমপেন

@ এমপেন ওয়ন্ট এটিকে সর্বোত্তম উপায়ে বা সর্বাধিক পাইথোনিক দাবি করে তবে নীচে আপনি যে ভিউতে প্রদর্শন করতে চান সেই মানগুলি পাওয়া উচিত / যাতে একটি HTML টেবিলের শিরোনাম আপনি চান। যেমন get_fields () একটি টুপল দেয়, আপনি এটির পুনরাবৃত্তি করতে পারবেন এবং অ্যাপ্লিকেশন নামের মতো মানগুলি পেতে পারেন M মডেল.ফিল্ড_নাম নীচে দ্বিতীয় বিন্দু থেকে মানগুলি পরিষ্কার করে, ক্ষেত্রের নাম হিসাবে আন্ডারস্কোর হিসাবে ব্যবহৃত হত পাশাপাশি তাদের একটি উপাধি তৈরি করুন, তাই প্রতিটি অনন্য পরিস্থিতির জন্য প্রয়োজনীয় হিসাবে সংশোধন করুন। clean_field_names = [str(h).split('.')[2].replace("_", " ").title() for h in all_fields]
আলেজান্দ্রো সুয়ারেজ

1
উদাহরণস্বরূপ উদাহরণটি all_fields = bp._meta.fields
হ'ল

টুইটগুলি দেখুন এটি সরাসরি ক্লাস থেকেও কাজ করে না? পরীক্ষা করার উদাহরণ নেই। যাইহোক উদাহরণটি উদাহরণস্বরূপ, সুতরাং এটি বিপি বা কমপক্ষে বিপি হতে হবে __ শ্রেণি__
মাকস

294

জ্যাঙ্গো সংস্করণ 1.8 এবং পরবর্তী:

আপনার ব্যবহার করা উচিত get_fields():

[f.name for f in MyModel._meta.get_fields()]

get_all_field_names()পদ্ধতি জ্যাঙ্গো 1.8 থেকে শুরু অবচিত এবং 1.10 সরিয়ে ফেলা হবে

উপরের লিঙ্কযুক্ত ডকুমেন্টেশন পৃষ্ঠাটি সম্পূর্ণ পিছনে-সামঞ্জস্যপূর্ণ বাস্তবায়ন সরবরাহ করে get_all_field_names()তবে বেশিরভাগ উদ্দেশ্যে পূর্ববর্তী উদাহরণটি ঠিক কাজ করা উচিত।


জ্যাঙ্গো সংস্করণ 1.8 এর আগে:

model._meta.get_all_field_names()

কৌতুক করা উচিত।

এটির জন্য একটি আসল মডেল উদাহরণ প্রয়োজন। আপনার সমস্ত কিছু যদি একটি সাবক্লাস হয় django.db.models.Modelতবে আপনার কল করা উচিতmyproject.myapp.models.MyModel._meta.get_all_field_names()


11
কেবল তাদের নাম নয়, অবজেক্টগুলিও চেয়েছিল। এটি model._meta.fieldsযদিও উপলব্ধ রয়েছে এবং তাদের নামগুলি এটি পুনরুদ্ধারযোগ্য field.nameবলে মনে হয়। আমি কেবল আশা করি এই তথ্যটি পুনরুদ্ধার করার এটি সবচেয়ে স্থিতিশীল উপায় :)
এমপেন

2
পুরোপুরি নিশ্চিত নয়। আন্ডারস্কোরটি এটি একটি অভ্যন্তরীণ এপিআই নির্দেশ করে বলে মনে হচ্ছে, জ্যাঙ্গো ছেলেরা যদি প্রকৃতপক্ষে জনসাধারণের পদ্ধতিতে কল করতে প্রচার করে তবে তা দুর্দান্ত django.db.models.Model। আমি এটি খনন করব এবং আমি কী দেখতে পাব তা দেখুন
রসপিডিয়া

2
আমার ধারণা অনুমানটির মাধ্যমে এটি _metaকরা একমাত্র উপায় ... অতিরিক্তভাবে _meta.many_to_manyমুনিটোম্যান ক্ষেত্রগুলি সন্ধান করুন!
বার্নহার্ড ভালান্ট

3
এটি একটি ভাল সমাধান তবে এই পদ্ধতিতে বিপরীত সম্পর্ক ক্ষেত্রগুলি যেমন একটি বিপরীত ফরেনকে এবং অন্তর্ভুক্তগুলি হুবহু "ক্ষেত্র" নয় includes যে কেউ প্রকৃত ক্ষেত্রগুলি আলাদা করতে জানেন?
ভাইরিডিস

2
@ অস্ট্রিয়া উইকিপিডিয়া: সবেমাত্র লক্ষ করা যায় যে ._মেটা এপিআই সর্বজনীন (যদিও এটি প্রাইভেট হিসাবে ব্যবহৃত হত, সম্ভবত যখন এই উত্তরটি প্রথম লেখা হয়েছিল): ডকস.ডজ্যাঙ্গোপ্রজেক্ট /en/1.8/ref/models/meta/…
নিক এস

76

এখানে get_all_related_fields()উল্লিখিত পদ্ধতিটি ১.৮ সালে হ্রাস করা হয়েছে । এখন থেকে এটি get_fields()

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

1
এটি এখন স্বীকৃত উত্তর হওয়া উচিত। সংশ্লেষ, এবং বিন্দু।
আরনাউদ পি

হ্যাঁ এই উত্তর।
এরিক

55

আমি এটি জাঙ্গো মডেলগুলিতে যুক্ত করতে বেশ সহায়ক বলে মনে করি:

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

এটি আপনাকে করতে দেয়:

for field, val in object:
    print field, val

2
ফরেনকি সম্পর্কে কী? আমার এর মতো ত্রুটি রয়েছেdjango.db.models.fields.related.RelatedObjectDoesNotExist: CustomModel has no custom_attribute.
সাক্রিস্ট

ForeignKeyআমার জন্য ভাল কাজ। যদিও, নিঃশব্দে সমস্ত ব্যতিক্রম ধরা একটি বিরোধী-নিদর্শন। ধরা আরও ভাল AttributeError, বা লগ অন্তত কিছু ব্যতিক্রম নিঃশব্দে গ্রাস করা হয়েছে।
সারদাথ্রিয়ন - এসই এর বিরুদ্ধে

1
self._meta.get_all_field_names()অবচয় এবং অপসারণ করা হয়েছে। আপনি এর মতো for field in self._meta.get_fields()এবং তারপরে কিছু ব্যবহার করতে পারেনyield (field.name, field.value_from_object(self))
ম্যাকএম

13

এই কৌশলটি করে। আমি কেবল এটি জাজানো 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


10

আপনার ক্লাসের কোনও উদাহরণ রয়েছে বা ক্লাস নিজেই রয়েছে এবং ক্ষেত্রগুলি পুনরুদ্ধার করার চেষ্টা করছেন কিনা তা পরিষ্কার নয় তবে উভয় উপায়ে নিম্নলিখিত কোডটি বিবেচনা করুন

একটি উদাহরণ ব্যবহার করে

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'

10
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


8

MyModel._meta.get_all_field_names()ছিল অবচিত বিভিন্ন সংস্করণ পিছনে মুছে জ্যাঙ্গো 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)
)))

6

কেবল যোগ করতে, আমি স্ব-অবজেক্টটি ব্যবহার করছি, এটি আমার পক্ষে কাজ করেছে:

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

5

অন্তত জাজানো ১.৯.৯ - এর সাথে আমি বর্তমানে যে সংস্করণটি ব্যবহার করছি - এর সাথে নোট করুন যে .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']

@ রোকলাইট দ্বারা প্রদর্শিত হিসাবে

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

4

সুতরাং আমি এই পোস্টটি সন্ধান করার আগে, আমি এটি সফলভাবে কাজ করতে পেলাম।

Model._meta.fields

এটি হিসাবে সমানভাবে কাজ করে

Model._meta.get_fields()

ফলাফলগুলির মধ্যে পার্থক্য কী তা আমি নিশ্চিত নই, যদি একটি থাকে তবে। আমি এই লুপটি চালিয়েছি এবং একই আউটপুট পেয়েছি।

for field in Model._meta.fields:
    print(field.name)

-2

কেন কেবল এটি ব্যবহার করবেন না:

manage.py inspectdb

উদাহরণ আউটপুট:

class GuardianUserobjectpermission(models.Model):
    id = models.IntegerField(primary_key=True)  # AutoField?
    object_pk = models.CharField(max_length=255)
    content_type = models.ForeignKey(DjangoContentType, models.DO_NOTHING)
    permission = models.ForeignKey(AuthPermission, models.DO_NOTHING)
    user = models.ForeignKey(CustomUsers, models.DO_NOTHING)

    class Meta:
        managed = False
        db_table = 'guardian_userobjectpermission'
        unique_together = (('user', 'permission', 'object_pk'),)

1
এটি প্রশ্নের উত্তর নয়।
শায়নে
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.