Django CreateView 在请求之间维护数据



我目前正在为使用外部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 请求之间维护这些数据,这样我就不需要再次获取数据,基于类的视图怎么可能,最好没有很多额外的工作?我正在考虑缓存请求,但如果用户提交时间太长,它并不能真正解决问题。

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

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

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

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

无论如何,由于看起来您正在处理 JSON 数据,并且文件大小不足以保证文件存储,因此我建议您只使用基于缓存的会话。

确保启用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()中访问会话数据。

最新更新