【问题标题】:Access a form method from generic.UpdateView in Django从 Django 中的 generic.UpdateView 访问表单方法
【发布时间】:2019-08-08 04:15:04
【问题描述】:

我有一个 generic.UpdateView 的视图,我需要访问一个表单方法 - get_hidden_fields()。如何访问它?

我目前使用的是self.form_class().get_hidden_fields(),但我不确定这是否正确。我认为它创建了一个新的表单实例,我想使用当前实例。

def get_context_data(self, **kwargs):
    cd = super().get_context_data(**kwargs)
    cd.update({
        'matches_list': self.page.object_list,
        'form_hidden_fields': list(self.form_class().get_hidden_fields()),
    })
    return cd

https://github.com/speedy-net/speedy-net/blob/staging/speedy/match/matches/views.py#L54

【问题讨论】:

  • 您可以将其设为@classmethod
  • @ruddra 我不想改变方法本身。

标签: python django django-forms django-views


【解决方案1】:

我可以直接从模板访问form方法:

{% if field.name in form.get_hidden_fields %}

link

但是,如果我需要从 Python 访问表单,我认为正确的方法是在 get_context_data 中使用 cd['form'](在调用 cd = super().get_context_data(**kwargs) 之后)。

def get_context_data(self, **kwargs):
    cd = super().get_context_data(**kwargs)
    cd.update({
        'matches_list': self.page.object_list,
        'form_hidden_fields': list(cd['form'].get_hidden_fields()),
    })
    return cd

【讨论】:

    【解决方案2】:

    更新 1:8 月 10 日

    def get_context_data(self, **kwargs):
        if "form" in kwargs:
            form = kwargs['form']
        else:
            form = self.get_form()
            kwargs['form'] = form
    
        cd = super().get_context_data(**kwargs)
        self.form_class()
        cd.update({
            'matches_list': self.page.object_list,
            'form_hidden_fields': list(form.get_hidden_fields()),
        })
        return cd
    

    这是您可以使用的另一种方法,因为当您调用get_context_data 时,它会创建它不存在的表单。这意味着您要么创建表单,要么让它创建表单。如果继承类的get_context_data 做到了,那么它会在kwargs 中做到,如果没有破解方法,您将无法提取。

    原始方法

    因此,您可以使用启动类的方法,也可以使用组合方法,其中相同的方法既可以用作类方法,也可以用作实例方法。该技术如下文所示

    Creating a method that is simultaneously an instance and class method

    下面是相同的演示

    import functools
    
    
    class combomethod(object):
        def __init__(self, method):
            self.method = method
    
        def __get__(self, obj=None, objtype=None):
            @functools.wraps(self.method)
            def _wrapper(*args, **kwargs):
                if obj is not None:
                    return self.method(obj, *args, **kwargs)
                else:
                    return self.method(objtype, *args, **kwargs)
    
            return _wrapper
    
    
    class SpeedyMatchSettingsMiniForm(object):
        @combomethod
        def get_fields(self):
            return ('gender_to_match', 'match_description', 'min_age_to_match', 'max_age_to_match', 'diet_match', 'smoking_status_match', 'relationship_status_match')
    
        @combomethod
        def get_visible_fields(self):
            return ('diet_match', 'min_age_to_match', 'max_age_to_match')
    
        @combomethod
        def get_hidden_fields(self):
            fields = self.get_fields()
            visible_fields = self.get_visible_fields()
            return (field_name for field_name in fields if (not (field_name in visible_fields)))
    
    
    print(list(SpeedyMatchSettingsMiniForm().get_hidden_fields()))
    print(list(SpeedyMatchSettingsMiniForm.get_hidden_fields()))
    

    输出是

    ['gender_to_match', 'match_description', 'smoking_status_match', 'relationship_status_match']
    ['gender_to_match', 'match_description', 'smoking_status_match', 'relationship_status_match']
    

    因此,在您的情况下,您可以直接使用 Class 对象

    【讨论】:

    • 感谢您的回答,但我不想更改表单本身。我正在寻找一种方法来使用generic.UpdateView 创建的实例。
    • 你检查kwargs了吗,调用get_context_data后应该有form
    • 是的,它有一个form 键。我想从 Python 访问它。
    • 这个答案太复杂我接受不了,我只需要来自get_context_datacd['form']。但是你给了我这个想法,所以我给了你赏金。谢谢!
    • 是的@Uri,你是对的,我在阅读你的回答后意识到这一点。我没有检查返回值。所以你的答案是对的。我的方法在其他情况下可能会有所帮助
    猜你喜欢
    • 1970-01-01
    • 2021-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-21
    • 2021-03-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多