【问题标题】:How to create instances of related models in Django如何在 Django 中创建相关模型的实例
【发布时间】:2011-01-29 17:24:54
【问题描述】:

我正在开发一个 CMSy 应用程序,我已经为其实现了一组模型,这些模型允许创建自定义模板实例,由多个字段组成并与特定客户相关联。最终目标是可以通过管理界面定义一个或多个具有一组自定义字段的模板并将其关联到客户,以便客户随后可以按照模板规定的格式创建内容对象。

我似乎已经把它连接起来,这样我就可以创建任意数量的模板对象,但我正在努力解决如何在这些模板中创建实例 - 实际内容对象。例如,我可以为客户“Acme”定义一个模板“Basic Page”,其中包含“Title”和“Body”字段,但我还没有弄清楚如何创建可以填写这些字段的 Basic Page 实例。

这是我的(有些省略的)模型...

class Customer(models.Model):
    ...

class Field(models.Model):
    label = models.CharField(max_length=255)
    component = models.ForeignKey(ContentType, 
            limit_choices_to={'id__in': component_choices}
            )
    fields = models.Manager()

class Template(models.Model):
    label = models.CharField(max_length=255)
    clients = models.ManyToManyField(Customer, blank=True)
    fields = models.ManyToManyField(Field, blank=True)

class ContentObject(models.Model):
    label = models.CharField(max_length=255)
    template = models.ForeignKey(Template)
    author = models.ForeignKey(User)
    customer = models.ForeignKey(Customer)
    mod_date = models.DateTimeField('Modified Date', editable=False)
    def __unicode__(self):
        return '%s (%s)' % (self.label, self.template)
    def save(self):
        self.mod_date = datetime.datetime.now()
        super(ContentObject, self).save()

提前感谢您的任何建议!

【问题讨论】:

    标签: python django models


    【解决方案1】:

    如果您想坚持这种模型架构,您需要向 ContentObject 类添加另一个字段,用于存储实际内容。可能是这样的:

    ContentObject(models.Model):
        ...
        fields_content = models.ManyToManyField(Field, through=FieldContent)
        ...
    

    然后:

    class FieldContent(models.Model):
        field = ForeignKey(Field)
        content_object = ForeignKey(ContentObject)
        content = CharField
    

    那么您显然应该确保(可能使用 pre_save 信号)对于给定的 ContentObject 实例,只有该实例模板中的字段才能进入 FieldContent 表。

    然后您可以通过以下方式创建实际内容:

    FieldContent.objects.create(field=your_field, content_object=your_content_object, content=content_given_by_the_customer)
    

    【讨论】:

    • 谢谢,帕瓦图尔。这似乎是在正确的轨道上;但是我已经有模型来存储实际内容,并且该内容可以是具有多个属性而不是单个字段的复杂对象。如果有帮助,我已经展示了更多的 Field 类;给定字段的基本内容模型在“组件”中表示。很明显,需要将每个字段及其内容链接到内容对象...以您的示例为例,有没有办法动态确定给定字段的正确实例类型?
    【解决方案2】:

    只是:

    my_customer.templates.add(my_template)
    

    其中my_customermy_template 分别是CustomerTemplate 的实例。

    the documentation for related objects

    【讨论】:

      【解决方案3】:

      对不起,如果我不清楚。问题是如何基于模板创建实例,而不是如何创建模板。

      我的模板类用于定义给定模板包含哪些字段以及客户可以使用哪些字段。我的 ContentObject 类旨在定义基于模板的内容记录。

      再次感谢!

      【讨论】:

      • 这个答案实际上只是对问题的澄清。您可能应该删除此答案并更新您的问题。
      【解决方案4】:

      为了扩展 pawartur 的答案,有几种方法可以处理字段的多种(可能很复杂)数据类型。您可以尝试的一种方法是使用模型继承,可能是这样的:

      class FieldContent(models.Model):
          field = models.ForeignKey(Field)
          content_object = models.ForeignKeyKey(ContentObject)
          def get_component(self):
              """Return the specific component instance for this field."""
              return self.field.get_object_for_this_type(pk=self.pk)
      

      然后你从这个基础模型中继承每个字段类型组件,例如:

      class SomeComponent(FieldContent):
          # specific fields for the component here
      

      然后您可以执行以下操作: somecontentobject.get(id=whatever).fieldcontent_set.get(whatever).get_component().specific_component_field

      要创建新的字段实例,您可能需要向字段模型添加一个辅助方法,例如:

          def create_content(self, content_object):
              return self.component.get_class().objects.create(
                content_object=content_object, field=self)
      

      需要注意的一点是,所有这些东西确实会让你与框架发生冲突,Django 过去为你做所有事情的地方(表单、管理员等)突然变成了一些需要整理的工作.可能值得研究一些现实生活中的项目如何处理它,Django-cms (django-cms.org) 可能是一个好的开始。

      只是一个警告:我没有测试这篇文章中的任何代码,因为我没有安装任何有用的计算机,但它通常应该没问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-03-21
        • 2021-03-09
        • 2019-08-01
        • 2013-03-25
        • 1970-01-01
        • 2013-02-11
        • 2023-02-11
        • 2017-05-30
        相关资源
        最近更新 更多