我已经差不多耗尽在这个问题上我的资源,所以我必须提交问题给社会。
场景:
在我的urls.py文件我有这样一个规律:
url(r'^entry_form/(?P<sheet_id>\d+)/', SheetWizard.as_view([Sheet1,Sheet2,Sheet3])),
当用户访问像“127.0.0.1/myapp/entry_form/77”一个网址我想有Django的渲染工作表Sheet1,但与具有值“77”中的一个字段最初输入。
初论:
我forms.py文件类似如下:
class Sheet1(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(Sheet1, self).__init__(*args, **kwargs)
#create a helper object
self.helper = FormHelper(self)
#dont render the form tags
self.helper.form_tag = False
#Make a nice layout
self.helper.layout = Layout(
TabHolder(
Tab(
'Sheet Information', #Tab name text
PrependedText('sheet_field', 'Django-'), #The field with prepended text
)
)
#Now set the initial value of the field to sheet_id from url pattern
self.fields['sheet_field'].initial = str(sheet_id)+'-'+ str( time() ).replace('.','_')
#??? Not sure where to get sheet_id from???
请注意,在最后一行有一个名为“sheet_id”变量,这应该是值“77”由用户输入的URL模式的到来。
问题:
到目前为止,我不确定如何从我的forms.py或views.py文件的URL模式访问值“sheet_id”。 由于这是一个基于类的观点,我不能简单地创建关键字“sheet_id =无”,又名这样的事情是行不通的:
class SheetWizard(SessionWizardView, sheet_id=None):
#this breaks
我已经能够得到一些数据使用和request.GET中像“127.0.0.1/myapp/entry_form/?sheet_id=77”的URL views.py,但我不知道如何管是进入SessionWizardView的第一种形式用户会话。
这将不胜感激,如果有人可以帮助我。 并感谢您的所有种类的智慧!
使用向导的dispatch
方法:
def dispatch(self, request, *args, **kwargs):
self.sheet_id = kwargs.get('sheet_id', None)
return super(SheetWizard, self).dispatch(request, *args, **kwargs)
然后使用self.sheet_id
内get_form_initial
方法来填充初始值的形式。
由于mariodev指着我在正确的方向。
我发现这个代码组合为我的应用程序的工作:
[urls.py]
url(r'^entry_form/(?P<sheet_id_initial>\d+)/', SheetWizard.as_view([Sheet1,Sheet2,Sheet3])),
[views.py]
class SheetWizard(SessionWizardView):
#some code here
def dispatch(self, request, *args, **kwargs):
self.sheet_id_initial = kwargs.get('sheet_id_initial', None)
return super(SheetWizard, self).dispatch(request, *args, **kwargs)
def get_form_initial(self, step):
initial = self.initial_dict.get(step, {})
if int(step) == 0:
initial.update({ 'sheet_id_initial': self.sheet_id_initial })
return initial
[forms.py]
class Sheet1(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(Sheet1, self).__init__(*args, **kwargs)
#create a helper object
self.helper = FormHelper(self)
#dont render the form tags
self.helper.form_tag = False
#Make a nice layout
self.helper.layout = Layout(
TabHolder(
Tab(
'Sheet Information', #Tab name text
PrependedText('sheet_field', 'Django-'), #The field with prepended text
)
)
#finally lets set the initial values
if 'initial'in kwargs:
initial = kwargs.pop('initial')
print initial
if 'sheet_id_initial' in initial:
sheet_id_initial = initial.pop('sheet_id_initial')
#this is where the value from sheet_id_initial is initialized in the field :)
self.fields['sheet_id_initial'].initial = str(sheet_id_initial)+'-'+ str( time() ).replace('.','_')
然而,这确实造成了新的问题。 我现在可以访问的第一个形式和sheet_id_initial在URL模式的值如预期的表单字段已添加,但是当按下提交按钮404页没有发现因POST不添加sheet_id_initial部分返回请求的URL。
[返回首页]
“”“”
未找到页面(404)请求方法:POST请求URL: HTTP://192.ip.address.1:8001 /片/ entry_form /
使用在first_project.urls定义的URL配置,Django的尝试这些URL模式,顺序如下:
^admin/
^Users/
^sheets/ ^entry_form/(?P<sheet_id_initial>\d+)/
当前的URL,张/ entry_form /,不符合任何这些。
因为你有DEBUG =真在你的Django settings文件你会看到这个错误。 更改为False,和Django会显示一个标准的404页。
“”“”
[附加信息]
以改变从中达到sheet_id变量,无论是从URL模式或POST数据是相当直截了当的方式:
首先在urls.py的正则表达式模式改变为一个简单的比赛,如:
urlpatterns = patterns('',
url(r'^entry_form/', SheetWizard.as_view([Sheet1,Sheet2,Sheet3])),
#url(r'^entry_form/(?P<sheet_id_initial>\d+)/', SheetWizard.as_view([Sheet1,Sheet2,Sheet3])), #'sheet_id_initial' would be picked up by "self.sheet_id_initial = kwargs.get('sheet_id_initial', None)" in SheetWizard.dispatch()
然后在views.py改变,像这样的调度重写方法分配:
class SheetWizard(SessionWizardView):
def dispatch(self, request, *args, **kwargs):
#self.sheet_id = kwargs.get('sheet_id_initial', None) #used to grab sheet_id_initial from url pattern
if self.request.GET.has_key('sheet_id_initial'):
self.sheet_id_initial = self.request.GET['sheet_id_initial'] #used to grab sheet_id_initial from QueryDict
return super(SheetWizard, self).dispatch(request, *args, **kwargs)
最后,如果你得到MultiValueDictKeyError,我添加了一个try-except块来get_form_initial(),对于从如果POST数据存在调度方法声明的变量的存在测试(但我不知道这是否是最好的方式来处理这个问题。)
所以在views.py添加这些行到get_form_initial():
class SheetWizard(SessionWizardView):
def get_form_initial(self, step):
initial = self.initial_dict.get(step, {})
if step == "0":
try:
self.sheet_id_initial #check for variable existence
#if we get past this line then the variable existed and we can update initial data
initial.update({ 'sheet_id_initial': self.sheet_id_initial })
except:
#variable didn't exist so lets just move on..
pass
return initial
[更新 - 最好的解决到目前为止]
这sessionwizard和基于类的观点可能有点棘手。 我发现,这两个以前的方法中有这样或那样的一些缺陷,并意识到我是在复杂的事情有点。 但是,大多数以前的代码中是必不可少的,但不是POST或URL模式我存储在会话中的POST数据,并在不同的URL访问它横跨形式!
现在我有一个表格,用户从开始说的地址:“ HTTP://192.ip.address.1:8001 /张/启动/ ”,它在形式的两个领域:“part_id_initial”和“sheet_id_initial”
当按下提交是用户被重定向到:“ HTTP://192.ip.address.1:8001 /张/ entry_form / ”但有是POST数据不能与重定向走HTTP的限制。
所以你可以保存会话POST数据并通过修改上面的代码,像这样使用它的另一种形式:
urls.py
url(r'^start/', 'process_forms.views.GetStarted'),
url(r'^entry_form/', SheetWizard.as_view([Sheet1,Sheet2,Sheet3])),
views.py
def GetStarted(request):
form = gettingStarted(request.POST or None)
if request.method == 'POST':
if form.is_valid():
data = form.cleaned_data
request.session['_old_post'] = request.POST #Store POST to be passed to SheetWizard
return redirect('/sheets/entry_form/')
return render_to_response('get_started.html',
locals(),
context_instance=RequestContext(request))
class SheetWizard(SessionWizardView):
def dispatch(self, request, *args, **kwargs):
old_post = request.session.get('_old_post') #Retrieve old POST data to set initial values on session form
if old_post.has_key('sheet_id_initial') and old_post.has_key('part_id_initial'):
self.sheet_id_initial = old_post['sheet_id_initial'] #used to grab sheet_id from QueryDict
self.part_id_initial = old_post['part_id_initial'] #used to grab sheet_id from QueryDict
return super(SheetWizard, self).dispatch(request, *args, **kwargs)
其余几乎完全一样的上方。 保存到会话中的POST数据一直是这样,我发现到目前为止最清洁和最优雅的修补程序。
希望这可以帮助!!
文章来源: Inserting initial data into a SessionWizardView form field either from a URL pattern or post data?