【问题标题】:Set parent in a ModelForm in Google App Engine在 Google App Engine 的 ModelForm 中设置父级
【发布时间】:2011-01-07 00:30:55
【问题描述】:

我想在通过 ModelForm 创建的实体中创建实体组关系。

如何传递父实例并在ModelForm中设置parent=属性?

【问题讨论】:

    标签: python django google-app-engine app-engine-patch


    【解决方案1】:

    我很想看看你是否能找到任何好的解决方案来解决这个问题。我自己的解决方案远非优雅,就是这样做:

    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
    

    【讨论】:

    • 我确认它有效。我会等待更优雅的解决方案,如果没有出现,我会将您的答案标记为已接受。谢谢您,您已获得 10 分。
    • 不幸的是,这是目前最好的方法。
    【解决方案2】:

    我继承了 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 中指定 key_name 的代码,而是将其作为参数传递给 create。

    * 代码修改自google.appengine.ext.db.djangoforms中原modelform的save方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-16
      • 2015-04-23
      • 1970-01-01
      • 1970-01-01
      • 2016-04-20
      • 2010-12-02
      • 2019-08-03
      • 2015-06-22
      相关资源
      最近更新 更多