2012-11-21 2 views
1

pyramid_simpleform says you can use bind(model) 쉽게 모델의 값으로 폼의 값을 변환 :pyramid_simpleform에서 bind (모델)를 사용하여 양식을 Deform의 모델로 변환하는 간단한 방법이 있습니까?

(아래 문서 pyramid_simpleform에서) 내가 어디에서나 deform documentation에 해당하는 방법을 찾을 수없는

def add(self): 
    form = Form(request, 
       defaults={"name" : "..."}, 
       schema=MyModelSchema) 

    if form.validate(): 
    obj = form.bind(MyModel()) 
    # persist model somewhere... 
    return HTTPFound(location="/") 

    return dict(renderer=FormRenderer(form)) 

... 또는 변형 된 방식으로이 작업을 수행 할 수있는 방법이 있습니까?

답변

4

변형은 모델에 대한 스키마 바인딩을 직접 지원하지 않지만 sqlalchemy를 사용하는 경우 ColanderAlchemy과 정확히 일치합니다. sqlalchemy 모델에서 변형에 의해 사용되는 소손 스키마를 생성하고 양식을 모델에 바인드합니다.

+0

어디에서 통합 할 수 있습니까? –

+0

ColanderAlchemy의 문서에는 다음과 같은 예가 있습니다. https://colanderalchemy.readthedocs.org/en/latest/deform.html – madjar

+0

스키마에서 양식을 묶는 것이지 양식에서 모든 값을 가져 오는 것이 아니라는 것을 보여줍니다 , bind를 simple_form과 같이 스키마를 통해 SQL Alchemy 모델로 전달합니다. 어떻게 그걸합니까? –

0

여기에는보기 전용 양식과 편집 양식을 비롯한 150 개의 답변이 나와 있습니다. 가장 단순한 유스 케이스의 경우 복잡하지 않을 수도 있지만 나에게 적합하도록 시간을 할애해야했다.

class FormView: 
    """A base class for views which utilize ColanderAlchemy to view/edit SQLAlchemy model instances.""" 

    #: If the child class is not overriding the rendering loop, point this to a template which provides the page frame and ``crud_content`` block. 
    base_template = None 

    #: List of SQLAlchemy and JSONProperty field names automatically mapped to a form 
    includes = ["id",] 

    def __init__(self, context, request): 
     self.context = context 
     self.request = request 

    def create_form(self, buttons=()): 
     """Automatically create a read-only collander schema + deform form based on the underlying SQLALchemy model. 

     :param buttons: Passed to Deform as form buttons 
     """ 
     obj = self.get_object() 
     includes = self.includes 
     schema = PropertyAwareSQLAlchemySchemaNode(obj.__class__, includes=includes) 
     self.customize_schema(schema) 
     schema = self.bind_schema(schema) 
     form = deform.Form(schema, buttons=buttons) 
     return form 

    def bind_schema(self, schema): 
     """Initialize Colander field dynamic default values. By default, don't do anything.""" 
     return schema 

    def get_crud(self): 
     """Get CRUD manager object for this view.""" 
     return self.context.__parent__ 

    def get_object(self): 
     """Get underlying SQLAlchemy model instance from current Pyramid traversing context.""" 
     return self.context.get_object() 

    def get_title(self): 
     """Get human-readable title for for template page title.""" 
     return "#{}".format(self.get_object().id) 

    def customize_schema(self, schema): 
     """After Colander schema is automatically generated from the SQLAlchemy model, edit it in-place for fine-tuning. 

     Override this in your view subclass for schema customizations. 
     """ 
     return 



class Show(FormView): 
    """Read-only view to SQLAlchemy model instance using Deform form generated by ColanderAlchemy. 
    """ 

    def get_title(self): 
     return "#{}".format(self.get_object().id) 

    @view_config(context=sqlalchemy.Resource, name="show", renderer="crud/show.html", permission='view') 
    def show(self): 
     """View for showing an individual object.""" 

     obj = self.context.get_object() 
     base_template = self.base_template 

     form = self.create_form() 
     appstruct = form.schema.dictify(obj) 
     rendered_form = form.render(appstruct, readonly=True) 

     crud = self.get_crud() 

     resource_buttons = dict(edit=self.request.resource_url(self.context, "edit"), delete=False) 

     title = current_view_name = self.get_title() 

     return dict(form=rendered_form, context=self.context, obj=obj, title=title, crud=crud, base_template=base_template, resource_buttons=resource_buttons) 


class Edit(FormView): 
    """Edit SQLAlchemy model instance using Deform form generated by ColanderAlchemy. 
    """ 

    # We display id field on the edit form and it needs special handling, because it is read-only 
    # See http://deformdemo.repoze.org/readonly_value_nonvalidation/ 
    includes = [ 
     colander.SchemaNode(colander.String(), 
      name="id", 
      missing=lambda node, kw: kw["obj"].id, 
      widget=deform.widget.TextInputWidget(readonly=True), 
     ) 
    ] 

    def get_title(self): 
     return "Editing #{}".format(self.get_object().id) 

    def create_form(self): 
     return super(Edit, self).create_form(buttons=("save", "cancel",)) 

    def bind_schema(self, schema): 
     return schema.bind(obj=self.context.get_object()) 

    @view_config(context=sqlalchemy.Resource, name="edit", renderer="crud/edit.html", permission='edit') 
    def edit(self): 
     """View for showing an individual object.""" 

     # SQLAlchemy model instance 
     obj = self.context.get_object() 
     base_template = self.base_template 

     # Create form, convert instance to Colander structure for Deform 
     form = self.create_form() 

     crud = self.get_crud() 

     resource_buttons = dict(show=self.request.resource_url(self.context, "show"), delete=False) 

     title = current_view_name = self.get_title() 

     if "save" in self.request.POST: 

      controls = self.request.POST.items() 

      try: 
       appstruct = form.validate(controls) 

       # Cannot update id, as it is read-only 
       del appstruct["id"] 

       form.schema.objectify(appstruct, obj) 

       # We do not need to explicitly call save() or commit() as we are using Zope transaction manager 

       messages.add(self.request, kind="success", msg="Changes saved.") 

       # Redirect back to view page after edit page has succeeded 
       return HTTPFound(self.request.resource_url(self.context, "show")) 

      except deform.ValidationFailure as e: 
       # Whoops, bad things happened, render form with validation errors 
       rendered_form = e.render() 

     elif "cancel" in self.request.POST: 
      # User pressed cancel 
      return HTTPFound(self.request.resource_url(self.context, "show")) 
     else: 
      # Render initial form view with populated values 
      appstruct = form.schema.dictify(obj) 
      rendered_form = form.render(appstruct) 

     return dict(form=rendered_form, context=self.context, obj=obj, title=title, crud=crud, base_template=base_template, resource_buttons=resource_buttons)