ใน Django คุณสามารถระบุความสัมพันธ์เช่น:
author = ForeignKey('Person')
และจากนั้นภายในก็มีการแปลงสตริง "บุคคล" Person
ลงในรูปแบบ
ฟังก์ชันนี้อยู่ที่ไหน อยากใช้ แต่หาไม่เจอ
ใน Django คุณสามารถระบุความสัมพันธ์เช่น:
author = ForeignKey('Person')
และจากนั้นภายในก็มีการแปลงสตริง "บุคคล" Person
ลงในรูปแบบ
ฟังก์ชันนี้อยู่ที่ไหน อยากใช้ แต่หาไม่เจอ
คำตอบ:
สำหรับ Django 3.0 มันคือ
AppConfig.get_model(model_name, require_ready=True)
สำหรับ Django 1.9 วิธีการคือ
django.apps.AppConfig.get_model(model_name)
.
- danihp
ในขณะที่ Django 1.7
django.db.models.loading
ถูกเลิกใช้งาน (ที่จะลบออกใน 1.9) เพื่อรองรับระบบโหลดแอปพลิเคชันใหม่
- Scott Woodall
พบแล้ว กำหนดไว้ที่นี่:
from django.db.models.loading import get_model
กำหนดเป็น:
def get_model(self, app_label, model_name, seed_cache=True):
from django.apps import AppConfig
django.apps.apps.get_model(model_name)
ไฟล์. วัตถุ AppConfig มีไว้สำหรับวัตถุประสงค์อื่นและต้องการให้คุณสร้างอินสแตนซ์ AppConfig เพื่อเรียกget_model()
ใช้
django.db.models.loading
ได้รับการคัดค้านใน Django 1.7 ( ถอดออกใน 1.9 ) ในความโปรดปรานของใหม่ระบบโปรแกรมโหลด
เอกสาร Django 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'>
สำหรับทุกคนที่ติดขัด (เหมือนที่ฉันทำ):
from django.apps import apps
model = apps.get_model('app_name', 'model_name')
app_name
ควรระบุโดยใช้เครื่องหมายคำพูดเท่าที่ควรmodel_name
(เช่นอย่าพยายามนำเข้า)
get_model
ยอมรับตัวพิมพ์เล็กหรือตัวพิมพ์ใหญ่ 'model_name'
"สตริง" แบบจำลองส่วนใหญ่ปรากฏเป็นรูปแบบ "appname.modelname" ดังนั้นคุณอาจต้องการใช้รูปแบบนี้กับ get_model
from django.db.models.loading import get_model
your_model = get_model ( *your_string.split('.',1) )
ส่วนของรหัส django ที่มักจะเปลี่ยนสตริงดังกล่าวให้เป็นโมเดลนั้นซับซ้อนกว่าเล็กน้อยซึ่งมาจาก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)
สำหรับฉันนี่ดูเหมือนจะเป็นกรณีที่ดีสำหรับการแยกสิ่งนี้ออกเป็นฟังก์ชันเดียวในรหัสหลัก อย่างไรก็ตามหากคุณทราบว่าสตริงของคุณอยู่ในรูปแบบ "App.Model" ซับสองตัวด้านบนจะใช้ได้
your_model = get_model(*your_string.rsplit('.', 1))
. ป้ายกำกับแอปบางครั้งเป็นรูปแบบจุด แต่ชื่อรุ่นจะเป็นตัวระบุที่ถูกต้องเสมอ
apps.get_model
ลักษณะเช่นนี้ไม่จำเป็นในใหม่ "ในฐานะทางลัดวิธีนี้ยังยอมรับอาร์กิวเมนต์เดียวในรูปแบบapp_label.model_name
"
วิธีที่มีความสุขในการทำสิ่งนี้ใน Django 1.7+ คือ:
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
ในกรณีที่คุณไม่ทราบว่ามีโมเดลของคุณอยู่ในแอปใดคุณสามารถค้นหาด้วยวิธีนี้:
from django.contrib.contenttypes.models import ContentType
ct = ContentType.objects.get(model='your_model_name')
model = ct.model_class()
โปรดจำไว้ว่า your_model_name ต้องเป็นตัวพิมพ์เล็ก
ฉันไม่แน่ใจว่าจะทำที่ไหนใน Django แต่คุณสามารถทำได้
การแม็พชื่อคลาสกับสตริงผ่านการสะท้อน
classes = [Person,Child,Parent]
def find_class(name):
for clls in classes:
if clls.__class__.__name__ == name:
return clls
อีกประการหนึ่งที่มีรหัสน้อยกว่าสำหรับคนขี้เกียจ ทดสอบใน Django 2+
from django.apps import apps
model = apps.get_model("appname.ModelName") # e.g "accounts.User"
นี่คือวิธีการเฉพาะ django ที่น้อยลงในการรับคลาสจากสตริง:
mymodels = ['ModelA', 'ModelB']
model_list = __import__('<appname>.models', fromlist=mymodels)
model_a = getattr(model_list, 'ModelA')
หรือคุณสามารถใช้ importlib ดังที่แสดงไว้ที่นี่ :
import importlib
myapp_models = importlib.import_module('<appname>.models')
model_a = getattr(myapp_models, 'ModelA')
โซลูชันปี 2020:
from django.apps import apps
apps.get_model('app_name', 'Model')
ต่อเช่นของคุณ:
apps.get_model('people', 'Person')