【问题标题】:How to initialise data on a non model form?如何在非模型表单上初始化数据?
【发布时间】:2015-01-29 09:31:41
【问题描述】:

关于不使用模型对象的表单/视图,我有一个小问题。我似乎几乎按照应有的方式设置了它,但我似乎无法弄清楚如何传递数据以初始化我的编辑表单中的字段。

我要做的是从使用 Delphi 开发的 REST 服务器获取数据。所以这个 django thingie 不会使用普通的 django ORM 模型。目前我有它的工作,所以我的应用程序显示它使用对服务器的 REST 调用获得的部门列表。每个部门都有自己的 ID 作为超链接。

我的下一步/我想做的事情是显示一个表单,用户可以在其中编辑所选部门的一些值。从逻辑上讲,一切似乎都按照应有的方式连接在一起(据我所知)。可悲的是......无论出于何种原因......我似乎无法将有关单击的 ID 甚至列表中选定对象的信息传递给详细信息视图。

有人能帮帮我吗?这是我到目前为止所拥有的:

urls.py:

# DelphiClient/urls.py
from django.conf.urls import patterns
from django.conf.urls import url

from . import views

urlpatterns = patterns("",
    url(
        regex=r"^Departments$",
        view=views.DelphiDepartmentsListView.as_view(),
        name="Departments"
    ),
    url(
        regex=r'^Department/(?P<pk>\d+)/$', 
        view=views.DepartmentFormView.as_view(), 
        name='department_update'
    ),
)

views.py:

# DelphiClient/views.py

...

from .client import DelphiClient
from .forms  import DepartmentForm

class DelphiDepartmentsListView(TemplateView):
    template_name = 'DelphiDepartmentList.html'

    def get_context_data(self, **kwargs):
        client = DelphiClient()
        departments = client.get_department()

        context = super(DelphiDepartmentsListView, self).get_context_data(**kwargs)
        context['departments'] = departments

        #client.update_department(1, 'Update From Django')
        return context

class DepartmentFormView(FormView):
    template_name = 'DepartmentUpdate.html'
    form_class = DepartmentForm
    success_url = '/DelphiClient/Departments'

    def get_initial(self, **kwargs):
        """
        Returns the initial data to use for forms on this view.
        """
        initial = super(DepartmentFormView, self).get_initial(**kwargs)

        # How can I get the ID passed along from the list view
        # so I can get the correct object from my REST server and
        # pass it along in the Initial ???

        return initial

    def form_valid(self, form):
        # This method is called when valid form data has been POSTed.
        # It should return an HttpResponse.
        print "form.data {0}".format(form.data)
        client = DelphiClient()
        client.update_department(form.data["flddepartmentId"],form.data["flddepartmenet"])

        return super(DepartmentFormView, self).form_valid(form)    

forms.py:

# DelphiClient/forms.py

from django import forms
from .client import DelphiClient


class DepartmentForm(forms.Form):
    # How can I fill in the values for these fields using an object passed in
    # thhrough Initial or the context?

    flddepartmentId = forms.IntegerField(label="Department ID") #, value=1)
    flddepartmenet   = forms.CharField(label="New Description", max_length=100)    

    def update_department(self, *args, **kwargs):
        #print "update_department"
        #print self.data        
        #print self.data["flddepartmenet"]
        client = DelphiClient()
        client.update_department(self.data["flddepartmentId"],self.data["flddepartmenet"])

以及表单的模板:

<h1>Update Department</h1>
<p>Update Department? {{ department.flddepartmentid }}</p>
<p>Something : {{ something }}</p>

<form action="" method="post">
     {% csrf_token %}
     {{ form.as_p }}

     <p><label for="id_flddepartmentId">Department ID:</label> <input id="id_flddepartmentId" name="flddepartmentId" type="number" value="1"></p>
<p><label for="id_flddepartmenet">New Description:</label> <input id="id_flddepartmenet" maxlength="100" name="flddepartmenet" type="text"></p>

    <input type="submit" value="OK">
</form>        

正如你所看到的......我很接近......但还没有雪茄 :-) 因为我对 Python / Django 完全陌生并且一直在学习,所以我不知道我在做什么做错了或我应该看的地方。

如果有人能够帮助我或为我指明正确的方向,我将不胜感激。

【问题讨论】:

    标签: python django forms django-forms formview


    【解决方案1】:

    位置和基于名称的参数分别存储在self.argsself.kwargs 中(see the docs 基于名称的过滤)。因此,您可以使用self.kwargs['pk'] 访问pk

    我不确定您是否应该在表单中包含 flddepartmentId 作为可编辑字段。这意味着用户可以转到/Department/1/,然后在提交表单时输入flddepartmentId=2。最好从表单中删除该字段,然后在调用 update_department 时使用 URL 中的值。

    client.update_department(self.kwargs['pk'],self.data["flddepartmenet"])
    

    如果您确定要在表单中包含flddepartmentId,那么您的get_initial 方法应如下所示: def get_initial(self, **kwargs): """ 返回用于此视图上的表单的初始数据。 """ initial = super(DepartmentFormView, self).get_initial(**kwargs)

        initial['flddepartmentId'] = self.kwargs['pk']
    
        return initial
    

    【讨论】:

    • 嗯......我确实非常接近......看起来你的建议很有效。你是对的......我不应该允许用户编辑 ID 字段。
    • 哦,在您看来……我目前的方法/结构/做事方式有什么好处吗?作为 Django 的新手,我想知道我是否正在使用最好的方法来解决我的问题。
    • 是的,你在正确的轨道上,所以我很乐意提供帮助 :)
    • 最后一个问题......我应该在 form_valid 中进行更新还是覆盖保存方法并在那里进行?
    • 我认为在form_valid 中更新是可以的。您可以删除表单的 update_department 方法,因为它没有被使用。最好访问form.cleaned_data 而不是form.data(来自用户的原始数据)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-01-04
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-01
    相关资源
    最近更新 更多