如何在forms.py定义中访问运行时request.session值?

时间:2018-05-25 14:58:58

标签: django

我有一个库存管理应用程序,它将服务于多个位置(在我的应用程序中称为上下文)。当用户登录时,他们当前的上下文将作为值存储在request.sessions中。

我希望用户只能浏览和检索自己位置的记录。

我一直试图通过过滤在表单定义中调用的查询集来填充选择下拉列表,即。

    referenced_catalog = forms.ModelChoiceField(
    queryset=Inventory_unit_catalog.objects.all().filter(parent_business_unit_context_id=user_context_id),

我尝试从各种SO帖子中实现几种不同(但相似)的方法,包括为表单定义init块,例如:

class InventoryStockAddForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        self.user_context_id = kwargs.pop('user_context_id', None)
        super(InventoryStockAddForm, self).__init__(*args, **kwargs)

    name = forms.CharField(max_length=96,widget=forms.TextInput(),required=True)

    referenced_catalog = forms.ModelChoiceField(
        queryset = Inventory_unit_catalog.objects.all().filter(parent_business_unit_context_id=self.user_context_id),
        label = u"",
        widget = ModelSelect2Widget(
            model=Inventory_unit_catalog,
            search_fields=['name__icontains'],
            attrs={'data-placeholder': 'Select catalog...', 'data-width': '35em'},
        required=False))

    class Meta():
        model = Inventory_unit_stock
        fields = ('name',)

(不同的SO答案有这样或那样的方式。)

然后在views.py中:

user_context_id = request.session.get('user_context_id')
...
add_form = InventoryStockAddForm(user_context_id=user_context_id)

我甚至尝试过按https://djangobook.com/using-sessions-views-2/使用SessionStore:

SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
s = SessionStore()
user_context_id = s['user_context_id']

但是在更新forms.py时它总是失败,因为Django验证了代码,并且在验证时无法找到键值。

任何建议都将不胜感激,谢谢!

1 个答案:

答案 0 :(得分:0)

您无法访问self.user_context_id内的referenced_catalog = forms.ModelChoiceField(...) - 该代码在加载模块时运行,而不是在表单初始化时运行。

相反,您应该在__init__方法中设置查询集。

class InventoryStockAddForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        self.user_context_id = kwargs.pop('user_context_id', None)
        super(InventoryStockAddForm, self).__init__(*args, **kwargs)
        self.fields['referenced_catalog'].queryset = Inventory_unit_catalog.objects.all().filter(parent_business_unit_context_id=self.user_context_id)

    referenced_catalog = forms.ModelChoiceField(
        queryset = Inventory_unit_catalog.objects.none(),
        label = u"",
        widget = ModelSelect2Widget(
            model=Inventory_unit_catalog,
            search_fields=['name__icontains'],
            attrs={'data-placeholder': 'Select catalog...', 'data-width': '35em'},
        required=False))