我正在尝试覆盖 django formtools 向导表单小部件,但它只是使用标准小部件

发布于 2025-01-19 16:13:47 字数 5064 浏览 3 评论 0原文

我有以下形式

class ProviderSignUp1(forms.ModelForm):
    class Meta:
        model = models.Provider
        fields = [ 
            'childcare_type_informal',
            'childcare_type_accredited',
        ]
        wigdets = {
            'childcare_type_informal': PatchRadioSelect(
                attrs={
                    'class':'form-control'
                }
            ),
            'childcare_type_accredited': PatchRadioSelect(
                attrs={
                    'class':'form-control'
                }
            )
        }

    def clean(self):
        cleaned_data = self.cleaned_data
        if cleaned_data['childcare_type_informal'] == True and cleaned_data['childcare_type_accredited'] == True:
            raise ValidationError("You must select only one type of childcare")
        if cleaned_data['childcare_type_informal'] == False and cleaned_data['childcare_type_accredited'] == False:
            raise ValidationError("You must select at least one type of childcare")

        return super().clean()

小部件定义为

from django.forms.widgets import RadioSelect

class PatchRadioSelect(RadioSelect):
    template_name = 'userprofiles/form_widgets/radio.html'
    option_template_name = 'userprofiles/form_widgets/radio_option.html'

我的向导是:

PROVIDER_SIGNUP_TEMPLATES = {
    'page0': 'userprofiles/provider_signup_wizard/page0.html',
    'page1': 'userprofiles/provider_signup_wizard/page1.html',
    'page2': 'userprofiles/provider_signup_wizard/page2.html',
    'page3': 'userprofiles/provider_signup_wizard/page3.html',
    'page4': 'userprofiles/provider_signup_wizard/page4.html',
    'page5': 'userprofiles/provider_signup_wizard/page5.html',
    'page6': 'userprofiles/provider_signup_wizard/page6.html',
    'page7': 'userprofiles/provider_signup_wizard/page7.html',
    'page8a': 'userprofiles/provider_signup_wizard/page8.html',
    'page8b': 'userprofiles/provider_signup_wizard/page8.html',
    'page9': 'userprofiles/provider_signup_wizard/page9.html',
    'page10': 'userprofiles/provider_signup_wizard/page10.html',
}

PROVIDER_SIGNUP_FORMS = [
    ("page0", forms.ProviderSignUp0),
    ("page1", forms.ProviderSignUp1),
    ("page2", forms.ProviderSignUp2),
    ("page3", forms.ProviderSignUp3),
    ("page4", forms.ProviderSignUp4),
    ("page5", forms.ProviderSignUp5),
    ("page6", forms.ProviderSignUp6),
    ("page7", forms.ProviderSignUp7),
    ("page8a", forms.ProviderSignUp8a),
    ("page8b", forms.ProviderSignUp8b),
    ("page9", forms.ProviderSignUp9),
    ("page10", forms.ProviderSignUp10),
]

def accredited_only_condition(wizard):
    cleaned_data = wizard.get_cleaned_data_for_step('page1') or {}
    return cleaned_data.get('childcare_type_accredited', True)

def informal_only_condition(wizard):
    cleaned_data = wizard.get_cleaned_data_for_step('page1') or {}
    return cleaned_data.get('childcare_type_informal', True)

class ProviderSignUpWizard(SessionWizardView):
    form_list = PROVIDER_SIGNUP_FORMS
    condition_dict = {
        'page2': accredited_only_condition,
        'page8a': accredited_only_condition,
        'page8b': informal_only_condition,
        'page9': informal_only_condition,
    }

    def get_form_instance(self, step):
        if step == 'page4':
            return self.instance_dict.get(step, self.request.user)    
        return self.instance_dict.get(step, self.request.user.provider)

    def get_template_names(self):
        return [PROVIDER_SIGNUP_TEMPLATES[self.steps.current]]

    def done(self, form_list, **kwargs):
        provider_instance = models.Provider.objects.get(id=self.request.user.provider.id)
        user_instance = models.User.objects.get(id=self.request.user.id)
        for form in form_list:
            provider_instance = construct_instance(form, provider_instance, form._meta.fields, form._meta.exclude)
            user_instance = construct_instance(form, user_instance, form._meta.fields, form._meta.exclude)
        
        provider_instance.save()
        user_instance.save()

        return redirect(self.request.user.get_provider_profile_url())


    def post(self, *args, **kwargs):
        form = self.get_form(data=self.request.POST, files=self.request.FILES)                                                      
        

        if form.is_valid():
            form.save()
            if 'services' in form.cleaned_data:
                models.Provider.objects.get(id=self.request.user.provider.id).services.set(form.cleaned_data['services'])
            if 'features' in form.cleaned_data:
                models.Provider.objects.get(id=self.request.user.provider.id).features.set(form.cleaned_data['features'])
            if 'informal_phrases' in form.cleaned_data:
                models.Provider.objects.get(id=self.request.user.provider.id).informal_phrases.set(form.cleaned_data['informal_phrases'])
        return super().post(*args, **kwargs) 

我的小部件被忽略,并且正在使用标准小部件。请注意,我似乎无法更改标准中的任何小部件,只能向现有小部件添加属性。我做错了什么?

I have the following form

class ProviderSignUp1(forms.ModelForm):
    class Meta:
        model = models.Provider
        fields = [ 
            'childcare_type_informal',
            'childcare_type_accredited',
        ]
        wigdets = {
            'childcare_type_informal': PatchRadioSelect(
                attrs={
                    'class':'form-control'
                }
            ),
            'childcare_type_accredited': PatchRadioSelect(
                attrs={
                    'class':'form-control'
                }
            )
        }

    def clean(self):
        cleaned_data = self.cleaned_data
        if cleaned_data['childcare_type_informal'] == True and cleaned_data['childcare_type_accredited'] == True:
            raise ValidationError("You must select only one type of childcare")
        if cleaned_data['childcare_type_informal'] == False and cleaned_data['childcare_type_accredited'] == False:
            raise ValidationError("You must select at least one type of childcare")

        return super().clean()

The widget is defined as

from django.forms.widgets import RadioSelect

class PatchRadioSelect(RadioSelect):
    template_name = 'userprofiles/form_widgets/radio.html'
    option_template_name = 'userprofiles/form_widgets/radio_option.html'

And my wizard is:

PROVIDER_SIGNUP_TEMPLATES = {
    'page0': 'userprofiles/provider_signup_wizard/page0.html',
    'page1': 'userprofiles/provider_signup_wizard/page1.html',
    'page2': 'userprofiles/provider_signup_wizard/page2.html',
    'page3': 'userprofiles/provider_signup_wizard/page3.html',
    'page4': 'userprofiles/provider_signup_wizard/page4.html',
    'page5': 'userprofiles/provider_signup_wizard/page5.html',
    'page6': 'userprofiles/provider_signup_wizard/page6.html',
    'page7': 'userprofiles/provider_signup_wizard/page7.html',
    'page8a': 'userprofiles/provider_signup_wizard/page8.html',
    'page8b': 'userprofiles/provider_signup_wizard/page8.html',
    'page9': 'userprofiles/provider_signup_wizard/page9.html',
    'page10': 'userprofiles/provider_signup_wizard/page10.html',
}

PROVIDER_SIGNUP_FORMS = [
    ("page0", forms.ProviderSignUp0),
    ("page1", forms.ProviderSignUp1),
    ("page2", forms.ProviderSignUp2),
    ("page3", forms.ProviderSignUp3),
    ("page4", forms.ProviderSignUp4),
    ("page5", forms.ProviderSignUp5),
    ("page6", forms.ProviderSignUp6),
    ("page7", forms.ProviderSignUp7),
    ("page8a", forms.ProviderSignUp8a),
    ("page8b", forms.ProviderSignUp8b),
    ("page9", forms.ProviderSignUp9),
    ("page10", forms.ProviderSignUp10),
]

def accredited_only_condition(wizard):
    cleaned_data = wizard.get_cleaned_data_for_step('page1') or {}
    return cleaned_data.get('childcare_type_accredited', True)

def informal_only_condition(wizard):
    cleaned_data = wizard.get_cleaned_data_for_step('page1') or {}
    return cleaned_data.get('childcare_type_informal', True)

class ProviderSignUpWizard(SessionWizardView):
    form_list = PROVIDER_SIGNUP_FORMS
    condition_dict = {
        'page2': accredited_only_condition,
        'page8a': accredited_only_condition,
        'page8b': informal_only_condition,
        'page9': informal_only_condition,
    }

    def get_form_instance(self, step):
        if step == 'page4':
            return self.instance_dict.get(step, self.request.user)    
        return self.instance_dict.get(step, self.request.user.provider)

    def get_template_names(self):
        return [PROVIDER_SIGNUP_TEMPLATES[self.steps.current]]

    def done(self, form_list, **kwargs):
        provider_instance = models.Provider.objects.get(id=self.request.user.provider.id)
        user_instance = models.User.objects.get(id=self.request.user.id)
        for form in form_list:
            provider_instance = construct_instance(form, provider_instance, form._meta.fields, form._meta.exclude)
            user_instance = construct_instance(form, user_instance, form._meta.fields, form._meta.exclude)
        
        provider_instance.save()
        user_instance.save()

        return redirect(self.request.user.get_provider_profile_url())


    def post(self, *args, **kwargs):
        form = self.get_form(data=self.request.POST, files=self.request.FILES)                                                      
        

        if form.is_valid():
            form.save()
            if 'services' in form.cleaned_data:
                models.Provider.objects.get(id=self.request.user.provider.id).services.set(form.cleaned_data['services'])
            if 'features' in form.cleaned_data:
                models.Provider.objects.get(id=self.request.user.provider.id).features.set(form.cleaned_data['features'])
            if 'informal_phrases' in form.cleaned_data:
                models.Provider.objects.get(id=self.request.user.provider.id).informal_phrases.set(form.cleaned_data['informal_phrases'])
        return super().post(*args, **kwargs) 

My widget is being ignored and the standard widget is being used. Please note, I seem unable to change any of the widgets from the standard and can only add attributes to the existing widget. What am I doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉墨 2025-01-26 16:13:47

以防万一其他人遇到同一问题,我发现如果我在向导中的第一个形式中定义__ INIT __,然后我可以在__ INT __ INT __ INT __中覆盖小部件。我需要使用它。但是,如果我不以第一种形式指定__ INIT __,则无效。

我认为这比解决方案更重要。

Just in case anyone else comes across the same issue, I found if I define __init__ within the first form in the wizard, I can then override the widgets within __init__ in whichever form I need to use it. But it doesn't work if I don't specify __init__ in the first form.

I think this more a workaround than solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文