জাঙ্গো: স্ট্রিং থেকে মডেল পাবেন?


133

জাজানোতে, আপনি সম্পর্কগুলি নির্দিষ্ট করতে পারেন:

author = ForeignKey('Person')

এবং তারপরে অভ্যন্তরীণভাবে এটি স্ট্রিং "ব্যক্তি" কে মডেলে রূপান্তর করতে হবে Person

এই কাজটি কোথায়? আমি এটি ব্যবহার করতে চাই, তবে এটি খুঁজে পাচ্ছি না।

উত্তর:


167

জ্যাঙ্গো 3.0 হিসাবে, এটি AppConfig.get_model(model_name, require_ready=True)

জঙ্গো ১.৯ হিসাবে পদ্ধতিটি রয়েছে django.apps.AppConfig.get_model(model_name)
- দানিহপ

জ্যাঙ্গো ১.7 হিসাবে django.db.models.loadingনতুন অ্যাপ্লিকেশন লোডিং সিস্টেমের পক্ষে অবমুক্ত করা হয়েছে (১.৯-এ সরানো হবে)।
- স্কট উডাল


এটি পেয়েছি। এটি এখানে সংজ্ঞায়িত করা হয়েছে:

from django.db.models.loading import get_model

সংজ্ঞায়িত:

def get_model(self, app_label, model_name, seed_cache=True):

11
এই সমাধানটি জ্যাঙ্গো ১.7 এ অবচয় করা হয়েছে, সমাধানের এই অন্যান্য উত্তরটি দেখুন: স্ট্যাকওভারফ্লো.com
টিম স্যেলোর

4
হাই @ পেন, আমি আপনাকে উত্তরটি আপডেট করার পরামর্শ দিচ্ছি। জাঙ্গোতে 1.9 এ get_model অ্যাপকনফাইগে সংজ্ঞায়িত করা হয়েছে :from django.apps import AppConfig
দানি

1
django.apps.appConfig একটি জেনারেটর টাইপ যা মডেল অবজেক্টের মতো কাজ করতে পারে না।
নীরজ কুমার

2
জ্যাঙ্গো সালে 1.7+ এটা ব্যবহার get_model () জ্যাঙ্গো অ্যাপ্লিকেশন রেজিস্ট্রি উপর, যার মাধ্যমে পাওয়া যায় করাই ভালো django.apps.apps.get_model(model_name)। AppConfig অবজেক্টগুলি ভিন্ন উদ্দেশ্যে তৈরি করা হয়েছে এবং কল করার জন্য আপনাকে একটি অ্যাপকনফিগ উদাহরণ তৈরি করতে হবে get_model()
zlovelady

2
জ্যাঙ্গো ১.১১ এর উত্তর দরকার @ ল্যুক_আউস
জিমার

132

django.db.models.loadingনতুন অ্যাপ্লিকেশন লোডিং সিস্টেমের পক্ষে জাজানো ১. 1. এ ( 1.9-এ সরানো ) অবমূল্যায়ন করা হয়েছিল ।

জাজানো 1.7 ডক্স পরিবর্তে আমাদের নিম্নলিখিতটি দেয়:

>>> from django.apps import apps
>>> User = apps.get_model(app_label='auth', model_name='User')
>>> print(User)
<class 'django.contrib.auth.models.User'>

আমি পাইডোকের "সনাক্ত" ফাংশনটি ব্যবহার করতাম ... এখানে পার্থক্যের বিষয়ে নিশ্চিত নই, তবে জাঙ্গোর মধ্যে থাকতে আমি এই পদ্ধতিতে স্যুইচ করেছি। ধন্যবাদ।
ওয়ারথ-কোডার

61

যে কেউ আটকা পড়ার জন্য (যেমন আমি করেছি):

from django.apps import apps

model = apps.get_model('app_name', 'model_name')

app_nameউদ্ধৃতি ব্যবহার করে তালিকাবদ্ধ করা উচিত, যেমন model_name(যেমন এটি আমদানির চেষ্টা করবেন না)

get_model লোয়ার কেস বা আপার কেস 'মডেল_নাম' গ্রহণ করে


32

বেশিরভাগ মডেল "স্ট্রিংস" "appname.modelname" ফর্ম হিসাবে উপস্থিত হয় তাই আপনি get_model এ এই পরিবর্তনটি ব্যবহার করতে চাইতে পারেন

from django.db.models.loading import get_model

your_model = get_model ( *your_string.split('.',1) )

জ্যাঙ্গো কোডের যে অংশটি সাধারণত এ জাতীয় স্ট্রিংগুলিকে একটি মডেলে রূপান্তরিত করে সেটিকে আরও জটিল করে তুলুন এটি থেকে django/db/models/fields/related.py:

    try:
        app_label, model_name = relation.split(".")
    except ValueError:
        # If we can't split, assume a model in current app
        app_label = cls._meta.app_label
        model_name = relation
    except AttributeError:
        # If it doesn't have a split it's actually a model class
        app_label = relation._meta.app_label
        model_name = relation._meta.object_name

# Try to look up the related model, and if it's already loaded resolve the
# string right away. If get_model returns None, it means that the related
# model isn't loaded yet, so we need to pend the relation until the class
# is prepared.
model = get_model(app_label, model_name,
                  seed_cache=False, only_installed=False)

আমার কাছে, এটি মূল কোডটির একক ফাংশনে বিভক্ত করার পক্ষে এটি একটি ভাল কেস বলে মনে হচ্ছে। তবে, আপনি যদি জানেন যে আপনার স্ট্রিংগুলি "অ্যাপ্লিকেশন। মডেল" ফর্ম্যাটে রয়েছে তবে উপরের দুটি লাইনার কাজ করবে।


3
আমি মনে করি 2nd লাইন হওয়া উচিত: your_model = get_model(*your_string.rsplit('.', 1))। অ্যাপ লেবেল কখনও কখনও বিন্দুযুক্ত ফর্ম্যাট হয় তবে মডেলের নাম সর্বদা একটি বৈধ শনাক্তকারী is
রকাল্লাইট

1
নতুনটিতে এটি প্রয়োজনীয় নয় বলে মনে হচ্ছে apps.get_model। "শর্টকাট হিসাবে, এই পদ্ধতিটি ফর্মের মধ্যে একটি যুক্তিও গ্রহণ করে app_label.model_name।"
রাইনে এভারেট

16

জ্যাঙ্গো 1.7+ এ করার জন্য ধন্য উপায় way

import django
model_cls = django.apps.apps.get_model('app_name', 'model_name')

সুতরাং, সমস্ত ফ্রেমওয়ার্ক টিউটোরিয়ালগুলির আধ্যাত্মিক উদাহরণে:

import django
entry_cls = django.apps.apps.get_model('blog', 'entry')  # Case insensitive

9

আপনার মডেলটি কোন অ্যাপে বিদ্যমান তা আপনি যদি না জানেন তবে আপনি এটি এইভাবে অনুসন্ধান করতে পারেন:

from django.contrib.contenttypes.models import ContentType 
ct = ContentType.objects.get(model='your_model_name') 
model = ct.model_class()

মনে রাখবেন যে আপনার_মোডেল_নামটি অবশ্যই ছোট হাতের হতে হবে।


4

জ্যাঙ্গোতে এটি কোথায় হয়েছে তা আমি নিশ্চিত নই, তবে আপনি এটি করতে পারতেন।

প্রতিবিম্বের মাধ্যমে স্ট্রিংয়ে শ্রেণীর নাম ম্যাপিং।

classes = [Person,Child,Parent]
def find_class(name):
 for clls in classes:
  if clls.__class__.__name__ == name:
   return clls

1
এটি কি ক্লাস .__ ক্লাস __.__ নাম__ বা স্রেফ সেলস .__ নাম__?
বিনায়ক কানিয়র্ককাল

4

অলসতার জন্য কম কোড সহ অন্য একটি উপস্থাপনা। জ্যাঙ্গো 2+ তে পরীক্ষিত

from django.apps import apps
model = apps.get_model("appname.ModelName") # e.g "accounts.User"

1

স্ট্রিং থেকে ক্লাস পাওয়ার জন্য এখানে কম জ্যাঙ্গো-নির্দিষ্ট পদ্ধতি রয়েছে:

mymodels = ['ModelA', 'ModelB']
model_list = __import__('<appname>.models', fromlist=mymodels)
model_a = getattr(model_list, 'ModelA')

বা আপনি এখানে প্রদর্শিত হিসাবে ইম্পোর্টলিব ব্যবহার করতে পারেন :

import importlib
myapp_models = importlib.import_module('<appname>.models')
model_a = getattr(myapp_models, 'ModelA')

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