插入初始数据转换为SessionWizardView表单字段无论是从一个URL模式或交数据?(Ins

2019-10-21 06:16发布

我已经差不多耗尽在这个问题上我的资源,所以我必须提交问题给社会。

场景:

在我的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的第一种形式用户会话。

这将不胜感激,如果有人可以帮助我。 并感谢您的所有种类的智慧!

Answer 1:

使用向导的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_idget_form_initial方法来填充初始值的形式。



Answer 2:

由于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?