在Django中的视图之间传递数据

时间:2017-06-27 13:28:21

标签: django

我有一个FormView(目前是一个WizardView,因为我有多个表单),它接收来自(匿名)用户的输入,并将要在请求中使用的已清理数据传递给外部api。

但是我不清楚如何最好地将从一个视图收到的数据传递到下一个视图?

从api收到的数据将显示在下一个视图中。 (如果数据是在内部保存的(而不是在外部api中),我可能会尝试使用通过会话从FormView传递给ListView的相关参数的ListView。

然而,api返回的数据将包含许多页面的数据。 在django中管理这个的最佳方法是什么? (这不需要是异步的,因为在用户继续之前需要返回数据。)

class QuotesWizard(SessionWizardView):
    def get_template_names(self):
        return [QUOTES_TEMPLATES[self.steps.current]]

    def dispatch(self, request, *args, **kwargs):
        if request.user.is_authenticated():
            return redirect(settings.LOGIN_REDIRECT_URL)
        return super().dispatch(request, *args, **kwargs)

    def done(self, form_list, form_dict, **kwargs):
        postcode = form_dict['postcode'].cleaned_data['postcode']
        service = form_dict['service'].cleaned_data['service']
        usage = form_dict['usage'].cleaned_data['usage']

        usage = convert_usage(usage)

        # get data from external api
        data = get_quotes(postcode, usage_ofgem, service_type)

        # redirect to quotes page - how to manage transfer of data?
        return redirect('quotes')

2 个答案:

答案 0 :(得分:0)

我在模块中有类似的方法,对地址数据也毫不奇怪。

我选择将结果存储在数据库中,因此我为其创建了一个模型。一个原因是通话次数有价格,所以每次拨打电话我都没有,我省钱。另一个原因是我不受远程API的限制:我的API对于浏览器和Django视图是一致的,如果某些东西发生了远程变化,我只能在一个地方修复它。

关键是创建一个QuerySet,在其中覆盖get方法,在你的情况下也是类似的过滤方法:

class PostcodeApiQuerySet(QuerySet):
# fields, other methods
    def get(self, *args, **kwargs):
        try:
            return super(PostcodeApiQuerySet, self).get(*args, **kwargs)
        except self.model.DoesNotExist:
            self._validate_lookup_kwargs(kwargs)
            pc = self._get_field_lookup_value('pc', kwargs)
            house_nr = self._get_field_lookup_value('house_nr', kwargs)
            house_nr_add = self._get_field_lookup_value('house_nr_add', kwargs)
            try:
                address = self._fetch_one(
                    pc, house_nr, house_nr_add=house_nr_add
                )
            except ObjectDoesNotExist as e:
                raise self.model.DoesNotExist(e.args[0])
            except KeyError as e:
                raise self.model.DoesNotExist(e.args[0])
            except ValueError as e:
                raise self.model.DoesNotExist(e.args[0])

            street = self._handle_foreign_for_address(address)
            instance = self.model(street=street, **address)
            instance.full_clean()
            instance.save()
            instance.refresh_from_db()
            return instance

此处调用的方法未包含在内,处理远程API以及将字段映射到API过滤器,但它应该为您提供一般概念。 filter方法会更复杂一些,因为您必须弄清楚您不具备的内容,以及您需要远程获取的内容。

完成此操作后,您可以将数据页面缩减为ID列表,这些ID应该很容易适合会话。然后,您可以使用ListView并覆盖get_queryset()来教授它从会话中获取的ID列表。

修改

所以流程是:

  1. FormView(GET):渲染选择表单
  2. Form_valid中的FormView(POST):应用过滤器以覆盖自定义查询集的过滤方法(另请参阅Manager.from_queryset)并在会话中存储ID
  3. FormView(POST),form_valid creates redirect到success_url
  4. ListView(GET)调用get_queryset您已经教会deal with会话中的ID
  5. 祝你好运!

答案 1 :(得分:-2)

有多种方法可以实现这一目标:

  1. 重定向时使用GET参数传递数据。这样,结果视图将是可缓存的和无状态的。的(推荐)

  2. 使用django sessions。将变量添加到会话,可以是    全球复兴。会话充当全局变量,因此请使用它们    只作为最后的手段。

  3. 如果您只想在会话中为下一个视图存储变量,请使用django messages