2012-02-13 3 views
3

Я хочу создать представление, которое может отображать ModelForm для различных моделей. Он делает это, получая тип содержимого модели, а затем динамически создавая модельную форму, связанную с этой конкретной моделью. Вот моя модель:Django - Динамический импорт модели

from django.db import models 

class SomeModel(models.Model): 
    name = models.CharField(max_length=150) 

    def __unicode__(self): 
     return self.name 

И в том же приложении есть forms.py со следующей формой:

from django.forms import ModelForm 

from someapp.models import SomeModel 

class SomeModelForm(ModelForm): 
    class Meta: 
     model = SomeModel 
     fields = ('name',) 

Так что я хочу сделать внутри мой файл зрения, это вернуть правильный формы для каждой модели динамически. Я пробовал следующее:

from django.db import models 
from someapp.forms import SomeModelForm 

    class SomeModel(models.Model): 
     name = models.CharField(max_length=150) 

     form = SomeModelForm 

     def __unicode__(self): 
      return self.name 

Но это не работает из-за очевидного кругового импорта. Кто-нибудь знает, как я могу это сделать? Я попытался использовать файл modelform_factory, но, похоже, он игнорирует любые мои пользовательские формы модели в forms.py.

EDIT: Я должен упомянуть, что у меня не будет экземпляра модели, только самого класса модели, поэтому есть метод, который внутри модели не работает (однако, он работает если вы вызываете его на экземпляр модели)

+0

В ответ на ваши изменения, вы можете использовать STATICMETHOD или classmethod. Я обновил свой пример. – Alasdair

ответ

6

Вы можете обойти круговой импорт, импортируя свою модельную форму внутри метода.

class SomeModel(models.Model): 
    name = models.CharField(max_length=150) 

    @staticmethod 
    def get_form_class(): 
     from someapp.forms import SomeModelForm 
     return SomeModelForm 

# in your view: 
SomeModel.get_form_class() 
+0

Ugh, статические методы, так очевидны! Большое спасибо, вы избавили меня от массивной головной боли. – Hanpan

3

Ввод импорта внутри метода на модели должно быть достаточно, чтобы получить вас вокруг круговой импорта, так что вместо того, что у вас есть, вы будете использовать:

class SomeModel(models.Model): 
    ... 
    def get_form(self): 
     from someapp.forms import SomeModelForm 
     return SomeModelForm 

Вы можете даже сделать это свойство, если вы хотите с:

form = property(get_form) 
3

Существует встроенный FUNC get_model для ленивых моделей импортеров.

from django.db.models import get_model 
SomeModel = get_model('your_app_name', 'SomeModel') 
0

Использование __import__ и getattr.

# models.py 
class SomeModel(models.Model): 
    ... 
    @classmethod 
    def get_form(cls): 
     try: 
      app = __import__(cls._meta.app_label) 
      forms = getattr(app, "forms") 
      return getattr(forms, "%sForm" % cls.__name__) 
     except: 
      return None 

# forms.py 
class SomeModelForm(forms.Form): 
    ... 

в виде вы можете получить вид назначает модели, как это:

# views.p 
from models import SomeModel 
... 

def myview(request): 
    form = SomeModel.getform() 
Смежные вопросы