【问题标题】:Django - Dynamically importing a models formDjango - 动态导入模型表单
【发布时间】:2012-02-13 16:37:40
【问题描述】:

我想创建一个能够为各种不同模型显示 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 中的任何自定义模型表单。

编辑:我应该提到我不会有模型的实例,只有模型类本身,所以在模型内部有一个方法不起作用(它确实,但是,如果您在模型的实例上调用它,则可以使用)

【问题讨论】:

  • 响应您的编辑,您可以使用静态方法或类方法。我更新了我的示例。

标签: django


【解决方案1】:

您可以通过在方法中导入模型表单来绕过循环导入。

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()

【讨论】:

  • 呃,静态方法,太明显了!非常感谢,你让我头疼不已。
【解决方案2】:

将导入放在模型上的方法中应该足以让您绕过循环导入,因此您可以使用:

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')
    

    【讨论】:

      【解决方案4】:

      使用__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()
      

      【讨论】:

        猜你喜欢
        • 2012-11-23
        • 2012-09-07
        • 2016-03-05
        • 2016-12-15
        • 1970-01-01
        • 2018-02-23
        • 2020-01-02
        • 2015-09-11
        • 2013-08-04
        相关资源
        最近更新 更多