代码之家  ›  专栏  ›  技术社区  ›  Iker Jimenez

在Google应用程序引擎中的模型窗体中设置父级

  •  4
  • Iker Jimenez  · 技术社区  · 16 年前

    我要在通过模型窗体创建的实体中创建实体-组关系。

    如何传递父实例并设置 parent= 模型窗体中的属性?

    2 回复  |  直到 15 年前
        1
  •  4
  •   Will McCutchen    16 年前

    我有兴趣看看你能不能找到解决这个问题的好办法。我自己的解决方案远远不够优雅,就是这样做:

    book = models.Book(title='Foo')
    chapter = models.Chapter(parent=book, title='dummy')
    form = forms.ChapterForm(request.POST, request.FILES, instance=chapter)
    

    基本上,我首先创建一个虚拟对象( chapter 在本例中)使用正确的父关系,然后将其作为 instance 窗体构造函数的参数。表单将使用请求中给定的数据覆盖我用于创建虚拟对象的一次性数据。最后,为了得到真正的孩子对象,我会这样做:

    if form.is_valid():
        chapter = form.save()
        # Now chapter.parent() == book
    
        2
  •  0
  •   Sverre Rabbelier    15 年前

    我将djangoforms.modelform子类化,并添加了一个create方法*:

    class ModelForm(djangoforms.ModelForm):
      """Django ModelForm class which uses our implementation of BoundField.
      """
    
      def create(self, commit=True, key_name=None, parent=None):
        """Save this form's cleaned data into a new model instance.
    
        Args:
          commit: optional bool, default True; if true, the model instance
            is also saved to the datastore.
          key_name: the key_name of the new model instance, default None
          parent: the parent of the new model instance, default None
    
        Returns:
          The model instance created by this call.
        Raises:
          ValueError if the data couldn't be validated.
        """
        if not self.is_bound:
          raise ValueError('Cannot save an unbound form')
        opts = self._meta
        instance = self.instance
        if self.instance:
          raise ValueError('Cannot create a saved form')
        if self.errors:
          raise ValueError("The %s could not be created because the data didn't "
                           'validate.' % opts.model.kind())
        cleaned_data = self._cleaned_data()
        converted_data = {}
        for name, prop in opts.model.properties().iteritems():
          value = cleaned_data.get(name)
          if value is not None:
            converted_data[name] = prop.make_value_from_form(value)
        try:
          instance = opts.model(key_name=key_name, parent=parent, **converted_data)
          self.instance = instance
        except db.BadValueError, err:
          raise ValueError('The %s could not be created (%s)' %
                           (opts.model.kind(), err))
        if commit:
          instance.put()
        return instance
    

    用法很简单:

    book = models.Book(title='Foo')
    form = forms.ChapterForm(request.POST)
    chapter = form.create(parent=book)
    

    请注意,我没有复制/粘贴允许您在request.post中指定密钥名称的代码,而是将其作为要创建的参数传递。

    *代码是从原始模型窗体的保存方法修改的 google.appengine.ext.db.djangoforms .