def __init__(self, cart, user, data=None, files=None, auto_id='id_%s', prefix=None, initial=None, error_class=ErrorList, label_suffix=None, empty_permitted=False): checkout_form_init_start.send(sender=self.__class__, instance=self) # Получаем мутабельную версию начальных значений from django.http import QueryDict if isinstance(initial, QueryDict): initial = initial.copy() # Заполнение начальных значений по профилю пользователя if user and initial is not None: # ToDo: по всей вероятности это можно сделать more pythonic initial['country'] = user.country initial['address'] = user.address initial['phone'] = user.phone initial['first_name'] = user.first_name initial['last_name'] = user.last_name initial['middle_name'] = user.middle_name initial['email'] = user.email super(CheckoutForm, self).__init__(data, files, auto_id, prefix, initial, error_class, label_suffix, empty_permitted) self.user = user self.cart = cart self.fields['phone'] = forms.CharField( label='Телефон', validators=[PhoneValidator(self.data.get('country', None))]) # Добавление полей оплаты и доставки self.fields['payment'] = forms.ChoiceField( label='Оплата', choices=[(name, gw()) for name, gw in gateways.items()], widget=CartRadioSelect) self.fields['shipment'] = forms.ChoiceField( label='Доставка', choices=[(name, mt(checkout_form=self)) for name, mt in methods.items()], widget=CartRadioSelect) # Обращение к Form.__getitem__ для получения BoundField self.personal_data = [ self['first_name'], self['last_name'], self['email'], self['phone'] ] self.shipping_data = [] # Обработка формы с учетом выбранной доставки и оплаты (initial - Ajax запрос, data - валидация формы) shipment = self.initial.get('shipment', self.data.get('shipment', None)) payment = self.initial.get('payment', self.data.get('payment', None)) if shipment in methods: shipping_method = methods[shipment](checkout_form=self) else: shipping_method = initial_method(checkout_form=self) shipping_method.update_form(self) self.shipping_method = shipping_method # Установка метода оплаты по умолчанию для данного метода доставки self.initial['payment'] = shipping_method.initial_gateway if payment in gateways: payment_gateway = gateways[payment]() else: payment_gateway = gateways[shipping_method.initial_gateway]() payment_gateway.update_form(self) self.payment_gateway = payment_gateway cart_price = cart.get_cart_summary()['cart_price'] shipping_price = shipping_method.get_price() self._cart_summary = { 'shipping_price': shipping_price, 'cart_price': cart_price, 'total_price': cart_price + shipping_price, 'final_price': cart_price + shipping_price } checkout_form_init_done.send(sender=self.__class__, instance=self)
class Meta: model = User # mini 是指能识别对象的最小单元 fields_mini = ['id', 'name', 'username'] # 只能写的字段, 这个虽然无法在框架上生效,但是更多对我们是提醒 fields_write_only = [ 'password', 'public_key', ] # small 指的是 不需要计算的直接能从一张表中获取到的数据 fields_small = fields_mini + fields_write_only + [ 'email', 'wechat', 'phone', 'mfa_level', 'source', 'source_display', 'can_public_key_auth', 'need_update_password', 'mfa_enabled', 'is_valid', 'is_expired', 'is_active', # 布尔字段 'date_expired', 'date_joined', 'last_login', # 日期字段 'created_by', 'comment', # 通用字段 'is_wecom_bound', 'is_dingtalk_bound', 'is_feishu_bound', 'is_otp_secret_key_bound', 'wecom_id', 'dingtalk_id', 'feishu_id' ] # 包含不太常用的字段,可以没有 fields_verbose = fields_small + [ 'total_role_display', 'org_role_display', 'mfa_level_display', 'mfa_force_enabled', 'is_first_login', 'date_password_last_updated', 'avatar_url', 'system_or_org_role' ] # 外键的字段 fields_fk = ['role', 'role_display'] # 多对多字段 fields_m2m = ['groups', 'groups_display', 'org_roles'] # 在serializer 上定义的字段 fields_custom = [ 'can_update', 'can_delete', 'login_blocked', 'password_strategy' ] fields = fields_verbose + fields_fk + fields_m2m + fields_custom read_only_fields = [ 'date_joined', 'last_login', 'created_by', 'is_first_login', ] extra_kwargs = { 'password': { 'write_only': True, 'required': False, 'allow_null': True, 'allow_blank': True }, 'public_key': { 'write_only': True }, 'is_first_login': { 'label': _('Is first login'), 'read_only': True }, 'is_valid': { 'label': _('Is valid') }, 'is_expired': { 'label': _('Is expired') }, 'avatar_url': { 'label': _('Avatar url') }, 'created_by': { 'read_only': True, 'allow_blank': True }, 'groups_display': { 'label': _('Groups name') }, 'source_display': { 'label': _('Source name') }, 'org_role_display': { 'label': _('Organization role name') }, 'role_display': { 'label': _('Super role name') }, 'total_role_display': { 'label': _('Total role name') }, 'role': { 'default': "User" }, 'is_wecom_bound': { 'label': _('Is wecom bound') }, 'is_dingtalk_bound': { 'label': _('Is dingtalk bound') }, 'is_feishu_bound': { 'label': _('Is feishu bound') }, 'is_otp_secret_key_bound': { 'label': _('Is OTP bound') }, 'phone': { 'validators': [PhoneValidator()] }, }
def __init__(self, *args, **kwargs): super(ProfileForm, self).__init__(*args, **kwargs) self.fields['phone'] = forms.CharField( label='Телефон', required=False, validators=[PhoneValidator(self.data.get('country', None))])