Django CreateView在请求之间维护数据

时间:2016-12-27 01:56:04

标签: django web-services state django-class-based-views

我目前正在使用基于类的视图来处理使用外部API并面临CreateView问题的服务,该问题不能在GET(呈现表单)和POST(上传数据)之间维护初始数据

此视图/路由实际上从Web服务获取数据,并且只需要向用户显示数据并上载文件。 Web服务请求包含在模型管理器的fetch方法中:

class OrderManager(models.Manager):
    def fetch(self, user):
        data = requests.get(...).json()

        return dict(student=user,
                    foo=data['bar'])

对于CreateView

class OrderForm(ModelForm):
    class Meta:
        fields = ['picture']
        model = Order

class OrderCreateView(LoginRequiredMixin, CreateView):
    form_class = OrderForm
    model = Order

    def get_initial(self):
        return self.model.objects.fetch(self.request.user)

它工作正常,当用户点击GET /order/new/时,它正确呈现从Web服务获取的数据并显示文件上载表单。但是,当提交表单时,它再次运行get_initial(...)而不是保留先前请求中的数据,并再次点击Web服务。

我想在GET和POST请求之间维护这些数据,因此我不需要再次获取数据,基于类的视图怎么可能,最好不需要额外的工作?我正在考虑缓存请求,但如果用户提交时间太长,它并没有真正解决问题。

1 个答案:

答案 0 :(得分:1)

您不应期望状态存储在请求之间的基于类的视图中。来自文档,

  

基于类的视图提供的每个请求都具有独立的状态;因此,在实例上存储状态变量是安全的(即self.foo = 3是一个线程安全的操作)。

这很容易被误解:表单一旦呈现,您的上下文就会消失,在下一个(POST)请求中,您的OrderCreateView将被实例化。

目前还不清楚您在模型管理器上获取数据的原因是什么?你是如何保存这些数据的?

在任何情况下,由于看起来您正在处理JSON数据并且文件大小不足以保证文件存储,我建议您只使用Cache-Based Session

实施例

确保启用SessionMiddleware后,将其添加到get_initial方法中。

class OrderCreateView(LoginRequiredMixin, CreateView):
    form_class = OrderForm
    model = Order

    def get_initial(self):
        # Inspect the user's session
        user_data = self.request.session.get('user_data', None)
        if user_data is None:
            user_data = self.model.objects.fetch(self.request.user)
            self.request.session['user_data'] = user_data
        return user_data

<小时/> 我仍然不确定您保存数据的位置,但如果它在表单中,您可能需要访问get_form_kwargs()中的会话数据。