Django - динамический импорт формы модели - PullRequest
3 голосов
/ 13 февраля 2012

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

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: Я должен упомянуть, что у меня не будет экземплярамодель, только сам класс модели, поэтому наличие метода, который внутри модели не работает (однако он работает, если вы вызываете его для экземпляра модели)

Ответы [ 4 ]

6 голосов
/ 13 февраля 2012

Вы можете обойти циклический импорт, импортировав форму модели внутри метода.

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()
3 голосов
/ 13 февраля 2012

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

from django.db.models import get_model
SomeModel = get_model('your_app_name', 'SomeModel')
3 голосов
/ 13 февраля 2012

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

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

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

form = property(get_form)
0 голосов
/ 11 марта 2013

Использование __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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...