class MingpianForm(forms.Form): name = fields.CharField(max_length=128, required=True, label='名字') weixin = fields.CharField(max_length=64, required=False, label='微信号') email = fields.EmailField(required=False, label='邮箱') phone_number = fields.CharField(max_length=64, required=False, label='电话') phone_number_2 = fields.CharField(max_length=64, required=False, label='电话2') address = fields.Field(required=False, label='坐标', widget=widgets.TextInput) remark = fields.Field(required=False, label='备注', widget=widgets.Textarea(attrs={'height': '100px'}))
class UserRegisterForm(forms.Form): user_name = fields.CharField(min_length=5, max_length=50) # password = fields.CharField(min_length=6, max_length=50) # 密码密文*输出 password = fields.Field(widget=widgets.PasswordInput()) real_name = fields.CharField(min_length=2, max_length=50) mail = fields.EmailField(min_length=6, max_length=50) # ap:管理员权限、pp:项目权限、mp:模块权限、gp:普通权限 # permission = fields.CharField(max_length=50) # permission = forms.ChoiceField(label="选择框",choices=(("ap","管理员权限"), # ("pp","项目权限"), # ("mp","模块权限"), # ("gp","普通权限"),)) # class UserLoginForm(forms.ModelForm): # # class Meta: # # model = User # # fields = ['user_name', 'password',] # class UserRegisterForm(forms.ModelForm): # # class Meta: # # model = User # # fields = ['user_name', 'password', 'real_name', 'mail']
class UserLoginForm(forms.Form): user_name = fields.CharField(min_length=5, max_length=50) # password = fields.CharField(min_length=6,max_length=50) # 密码密文*输出 password = fields.Field(widget=widgets.PasswordInput())
class DetailForm(forms.Form): inp = fields.Field( #error_messages中的err1与RegexValidator中的code='err1'对应 #error_messages的优先级高,如果表单输入的不是数字,会提示 '类型不符合要求' validators=[RegexValidator(r'^[0-9]+$', '请输入数字', code='err1'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头', code='err2')], error_messages={'err1': '类型不符合要求', 'err2': '格式不符合要求'} )
def coercer(self): """ Form field to be used to coerce data types """ if not self._coercer: self._coercer = self.formfield( localize=True) or djangofields.Field(localize=True) return self._coercer
class HeavyProductForm(ProductForm): weight = fields.DecimalField(max_digits=6, decimal_places=1) description = fields.Field(widget=widgets.HiddenInput, initial='XY') class Meta: model = Product entangled_fields = {'properties': ['weight']} field_order = ['name', 'tenant', 'active', 'weight']
class PeerToPeerQuestionnaireForm(forms.Form): team = django_models.ModelChoiceField(queryset=Team.objects.all(), disabled=True, required=True) questionnaire_type = django_models.ModelChoiceField( queryset=QuestionnaireType.objects.all(), disabled=True) target = django_fields.Field( required=True, widget=django_widgets.HiddenInput(attrs={'readonly': True})) def __init__(self, questionnaire_type, team, engagement_metrics, *args, **kwargs): super(PeerToPeerQuestionnaireForm, self).__init__(*args, **kwargs) for idx, engagement_metric in enumerate(engagement_metrics): metric_index = self.get_metric_index(idx) value_index = self.get_value_index(idx) self.fields[metric_index] = django_models.ModelChoiceField( queryset=EngagementMetric.objects.all(), disabled=True, initial=engagement_metric) self.fields[value_index] = django_fields.Field( widget=widgets.SlideiOSWidget(max=10)) self.fields['team'].initial = team self.fields['questionnaire_type'].initial = questionnaire_type self.engagement_metrics = len(engagement_metrics) def get_metric_index(self, idx): return "answer_metric_%d" % idx def get_value_index(self, idx): return "answer_value_%d" % idx def save(self): questionnaire = Questionnaire() questionnaire.questionnaire_type = self.cleaned_data[ 'questionnaire_type'] questionnaire.save() questionnaire.targets = [self.cleaned_data['target']] questionnaire.save() team = self.cleaned_data['team'] team_questionnaire = TeamQuestionnaire(questionnaire=questionnaire, team=team) team_questionnaire.save() for idx in range(0, self.engagement_metrics): value = self.cleaned_data[self.get_value_index(idx)] engagement_metric = self.cleaned_data[self.get_metric_index(idx)] answer = Answer(questionnaire=questionnaire, engagement_metric=engagement_metric, value=value) answer.save() return questionnaire
def add_fields(self, form, index): info = meta.model_info(self.model) if form.instance in self.session: for name in info.primary_keys: pk_field = djangofields.Field(initial=getattr( form.instance, name, None), widget=HiddenInput) form.fields[name] = pk_field super(BaseModelFormSet, self).add_fields(form, index)
class DetailForm(forms.Form): inp = fields.Field( validators=[RegexValidator(r'^[0-9]+$', '格式错误', 'invalid')], ) #二次验证函数的名字是固定写法,以clear_开头,后面跟上字段的变量名 def clean_inp(self): #通过了validators的验证之后,在进行二次验证 value = self.cleaned_data['inp'] if "123" in value: raise ValidationError('内容不符合要求', 'invalid') #通过了二次验证之后,返回表单数据,通过value_dic = obj.clean()能够得到验证通过后的表单数据 return value
def __init__(self, questionnaire_type, team, engagement_metrics, *args, **kwargs): super(PeerToPeerQuestionnaireForm, self).__init__(*args, **kwargs) for idx, engagement_metric in enumerate(engagement_metrics): metric_index = self.get_metric_index(idx) value_index = self.get_value_index(idx) self.fields[metric_index] = django_models.ModelChoiceField( queryset=EngagementMetric.objects.all(), disabled=True, initial=engagement_metric) self.fields[value_index] = django_fields.Field( widget=widgets.SlideiOSWidget(max=10)) self.fields['team'].initial = team self.fields['questionnaire_type'].initial = questionnaire_type self.engagement_metrics = len(engagement_metrics)
class CategoryFormBase(BaseModelForm): class Meta: model = get_category_model() exclude = ['seq', '_nav'] widgets = { 'title': forms.TextInput(attrs={ 'class': 'slugify', 'autocomplete': 'off' }), 'slug': forms.TextInput(attrs={ 'class': 'slug', 'autocomplete': 'off' }), '_excerpt': widgets.Textarea(attrs={'rows': '8'}), '_legacy_urls': widgets.Textarea(attrs={'rows': '4'}), 'description': EditableHtmlWidget(no_label=True, full_height=True), 'google_product_category': forms.Select(attrs={'class': 'select-tags'}) } tabs = [{ 'title': 'Title', 'fields': [ 'title', 'slug', 'parent', '_legacy_urls', '_excerpt', '_meta_title', '_meta_description', '_meta_keywords', '_meta_preview' ] }, { 'title': 'Content', 'fields': ['description'] }, { 'title': 'Gallery', 'fields': ['image', '_gallery_images'] }, { 'title': 'Options', 'fields': [ 'nav', 'navigation_title', 'enabled', 'auth_required', 'ordering_default', 'google_product_category' ] }] sections = { 'title': 'Category Data', '_excerpt': 'Excerpt', '_meta_title': 'Meta Data', '_meta_preview': 'Search Result Preview', 'nav': 'Navigation', 'enabled': 'Options' } parent = BrowseCategoryField( required=False, help_text='The parent category of this category.') _meta_preview = fields.Field( label=None, required=False, help_text='This preview is for demonstration purposes only ' +\ 'and the actual search result may differ from the preview. ' ) image = BrowseImagesField( required=False, help_text= 'Choose the main image that is used to represent this category.') _gallery_images = GalleryField( label='Image Gallery', required=False, queryset=Media.objects.filter(is_image=True), help_text='Add an arbitarily number of images to this category.') nav = forms.MultipleChoiceField( label='Navigation', required=False, widget=forms.CheckboxSelectMultiple, choices=settings.CMS_NAVIGATION, help_text='Tick the navigation sections in which this page ' + 'should appear in.') def configure(self, request, instance, edit): super(CategoryFormBase, self).configure(request, instance, edit) # meta preview control self.fields['_meta_preview'].widget = MetaPreviewWidget( attrs={ 'class': 'no-label', 'path': request.path_info, 'form': self }) # navigation if edit or self.is_duplicate: self.fields['nav'].initial = instance.nav # product ordering (only present choices that have been # activated in settings)... if hasattr(request.settings, 'get_product_ordering_choices'): self.fields['ordering_default'].choices = \ [('', '-------')] + request.settings.get_product_ordering_choices(has_subcategories=True) else: self.fields['ordering_default'].choices = [('', '-------')] def clean__legacy_urls(self): # remove \r from legacy_urls legacy_urls = self.cleaned_data.get('_legacy_urls') if legacy_urls: return legacy_urls.replace('\r', '') return legacy_urls def clean_parent(self): parent = self.cleaned_data.get('parent') if parent: # tree node cannot have itself as a parent if parent.id and self.instance.id and parent.id == self.instance.id: raise forms.ValidationError('Cannot have itself as parent.') # new parent node cannot be a child of the node we are editing if is_any_child_of(parent, self.instance): raise forms.ValidationError( 'New parent cannot be a child of this category.') return parent
class ProductFormBase(BaseModelForm): class Meta: model = get_product_model() exclude = ['seq', 'varieties', 'delivery_options', '_related_products'] widgets = { 'title': forms.TextInput(attrs={ 'class': 'slugify', 'autocomplete': 'off' }), 'slug': forms.TextInput(attrs={ 'class': 'slug', 'autocomplete': 'off' }), 'price': BootstrapTextInput(prepend=settings.CURRENCY, attrs={'class': 'input-medium'}), 'deposit': BootstrapTextInput(prepend=settings.CURRENCY, attrs={'class': 'input-medium'}), 'rrp': BootstrapTextInput(prepend=settings.CURRENCY, attrs={'class': 'input-medium'}), 'previous_price': BootstrapTextInput(prepend=settings.CURRENCY, attrs={'class': 'input-medium'}), 'finance_options': forms.CheckboxSelectMultiple() } tabs = [{ 'title': 'Title', 'fields': [ 'title', 'slug', 'category', 'categories', 'legacy_url', 'excerpt', '_meta_title', '_meta_description', '_meta_keywords', '_meta_preview' ] }, { 'title': 'Content', 'fields': ['_excerpt', 'description'] }, { 'title': 'Price and Availability', 'fields': [ 'rrp', 'previous_price', 'price', 'draft', 'non_returnable', 'collection_only', 'pre_order', 'deposit', 'loan_exempt', 'finance_options', 'exempt_from_free_delivery', 'exempt_from_discount', 'feed_google', 'feed_amazon', 'stock', 'stocklevel', 'sku_enabled', 'sku', 'barcode_system', 'barcode', 'part_number', ] }, { 'title': 'Gallery', 'fields': ['image', '_gallery_images'] }, { 'title': 'Related Products', 'fields': ['_related_products_collection'] }, { 'title': 'SKU / Inventory', 'fields': ['_inventory'] }] sections = { 'title': 'Product Data', '_excerpt': 'Excerpt', '_meta_title': 'Meta Data', 'barcode_system': 'Identification', 'stock': 'Stock', 'sku_enabled': 'SKU / Inventory', '_meta_preview': 'Search Result Preview', 'rrp': 'Price', 'draft': 'Options', 'pre_order': 'Pre-order', 'loan_exempt': 'Finance', 'exempt_from_free_delivery': 'Exemption', 'feed_google': 'Channel Feeds', 'image': 'Product Images' } category = BrowseCategoryField( required=True, help_text='The category this product is listed under.') _meta_preview = fields.Field( label=None, required=False, help_text='This preview is for demonstration purposes only ' +\ 'and the actual search result may differ from the preview.', ) image = BrowseImagesField( required=False, help_text= 'Choose the main image for this product that is used on the product listing page.' ) _gallery_images = GalleryField( label='Image Gallery', required=False, queryset=Media.objects.filter(is_image=True), help_text= 'Add an arbitrarily number of images that are presented on the product details page.' ) _related_products_collection = ModelCollectionField( label='Related Products', required=False, queryset=get_product_model().objects.all(), url='/admin/products/', title='Products', model_title='Products', help_text= 'Add an arbitrarily number of related products to this product.') categories = ModelCollectionField( label='Categories', add_label='Add Category', required=True, queryset=get_category_model().objects.all(), url='/admin/categories/', title='Categories', model_title='Categories', viewmode=ModelCollectionField.VIEWMODE_LIST, allow_duplicates=False, sortable=False, help_text= 'Add an arbitrarily number of categories this product is listed under.' ) _inventory = RelatedListingField(view=InventoryView()) def configure(self, request, instance, edit): super(ProductFormBase, self).configure(request, instance, edit) # meta preview control self.fields['_meta_preview'].widget = MetaPreviewWidget( attrs={ 'class': 'no-label', 'path': request.path_info, 'form': self }) # excerpt self.fields[ '_excerpt'].help_text = 'Provide your elevator pitch to the customer (max. %d characters)' % settings.CMS_EXCERPT_LENGTH if request.settings.barcode_system and request.settings.sku_is_barcode: self.remove_field('sku') self.fields['barcode'].label = 'SKU / Barcode' self.fields[ 'barcode'].help_text = 'SKU / Barcode (%s)' % request.settings.barcode_system.upper( ) # multiple categories if settings.SHOP_MULTIPLE_CATEGORIES: self.remove_field('category') else: self.remove_field('categories') # loan applications if settings.SHOP_LOAN_ENABLED: queryset = FinanceOption.objects.filter( enabled=True, per_product=True).order_by('seq') self.fields['finance_options'].queryset = queryset if queryset.count() == 0: self.remove_field('finance_options') self.update_sections() else: self.remove_field('finance_options') self.remove_field('loan_exempt') # SKU / inventory if not (instance and instance.sku_enabled): self.remove_tab('SKU / Inventory') self.update_sections() def clean_slug(self): slug = self.cleaned_data.get('slug') if slug: products = get_product_model().objects.filter(slug=slug) if self._edit and self._instance: products = products.exclude(pk=self._instance.pk) if products.count() > 0: raise forms.ValidationError( 'This slug is already used. Please choose a different slug.' ) return slug def clean_excerpt(self): excerpt = self.cleaned_data.get('_excerpt') if excerpt: if len(excerpt) > settings.CMS_EXCERPT_LENGTH: raise forms.ValidationError( 'The maximum allowed length is %d characters.' % settings.CMS_EXCERPT_LENGTH) return excerpt def clean_price(self): return clean_price(self, 'price', self.cleaned_data) def clean_rrp(self): return clean_price(self, 'rrp', self.cleaned_data) def clean_previous_price(self): return clean_price(self, 'previous_price', self.cleaned_data) def clean(self): d = super(ProductFormBase, self).clean() barcode_system = d.get('barcode_system') barcode = d.get('barcode') if barcode_system is None: barcode_system = self._request.settings.barcode_system # verify that the barcode is correct... if barcode and barcode_system: try: d['barcode'] = verify_barcode(barcode_system, barcode) except BarcodeError, e: self.field_error('barcode', e.msg) return d
class PageFormBase(BaseModelForm): """ Form for editing CMS pages. This is the base form class for cms pages and cms entities. However, when deriving new forms, use PageForm or EntityForm. """ class Meta: exclude = ['_nav', '_data'] widgets = { 'title': forms.TextInput(attrs={ 'class': 'slugify', 'autocomplete': 'off' }), 'slug': forms.TextInput(attrs={ 'class': 'slug', 'autocomplete': 'off' }), 'seq': NumberInput(attrs={ 'class': 'input-mini', 'min': '0' }), '_excerpt': widgets.Textarea(attrs={'rows': '8'}), '_meta_description': widgets.Textarea() } tabs = [{ 'title': 'Content', 'fields': [] }, { 'title': 'Title', 'fields': [ 'title', 'slug', 'legacy_url', '_excerpt', '_meta_title', '_meta_description', '_meta_keywords', '_meta_preview', ] }, { 'title': 'Presentation', 'fields': [ 'template', ] }, { 'title': 'Gallery', 'fields': ['image', '_gallery_images'] }, { 'title': 'Visibility', 'fields': ['disabled', 'sitemap', 'seq'] }] sections = { 'title': 'Page Data', '_excerpt': 'Excerpt', '_meta_title': 'Meta Data', '_meta_preview': 'Search Result Preview', 'template': 'Template', 'image': 'Primary Image and Gallery' } limits = { '_meta_title': FormInputLimit(65), '_meta_description': FormInputLimit(240) } image = BrowseImagesField(required=False) _gallery_images = ModelCollectionField( label='Image Gallery', required=False, queryset=Media.objects.filter(is_image=True), url='/admin/images/', title='Gallery', model_title='Images', help_text='Add an arbitrarily number of images to this page.') _meta_preview = fields.Field( label=None, required=False, help_text='This preview is for demonstration purposes only ' + \ 'and the actual search result may differ from the preview.' ) parent = BrowsePagesField( required=False, help_text='Select the parent page for this page for the purpose of ' + \ 'presenting multi-level navigation.' ) def clean_legacy_url(self): """ Allow a full domain name to be copy into the legacy_url field and have the absolute path extracted automatically. """ legacy_url = self.cleaned_data.get('legacy_url') if legacy_url: legacy_url = to_legacy_url(legacy_url) return legacy_url def clean(self): """ Detect navigation changes """ cleaned_data = super(PageFormBase, self).clean() if self._instance and self._instance.pk: nav_changed = (self.cleaned_data.get('title') != getattr( self._instance, 'title', None) or self.cleaned_data.get('navigation_title') != getattr(self._instance, 'navigation_title', None) or self.cleaned_data.get('slug') != getattr( self._instance, 'slug', None)) if nav_changed: self._instance.nav_updated_on = datetime.now() return cleaned_data def configure(self, request, instance, edit): """ Configure form """ super(PageFormBase, self).configure(request, instance, edit) from cubane.cms.templatetags.cms_tags import rewrite_image_references # create textarea field for each slot. if self.is_tabbed: for slotname in settings.CMS_SLOTNAMES: fieldname = 'slot_%s' % slotname self.fields[fieldname] = forms.CharField( required=False, widget=forms.Textarea( attrs={ 'class': 'editable-html preview no-label full-height', 'data-slotname': slotname })) self._tabs[0]['fields'].append(fieldname) # load initial content for each slot. if edit or self.is_duplicate: for slotname in settings.CMS_SLOTNAMES: fieldname = 'slot_%s' % slotname self.fields[fieldname].initial = \ rewrite_image_references(instance.get_slot_content(slotname)) self.fields['_meta_preview'].widget = MetaPreviewWidget( attrs={ 'class': 'no-label', 'path': request.path_info, 'form': self })
class DetailForm(forms.Form): # 使用自定义验证规则 inp = fields.Field(validators=[mobile_validate, ], error_messages={'required': '手机不能为空'}, widget=widgets.TextInput(attrs={'placeholder': u'手机号码'}))
class DetailForm(forms.Form): inp = fields.Field( #表单输入必须是数字,并且数字必须是159开头 validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')], )