django的附加功能
djextra的Python项目详细描述
django的附加代码
这是什么?
此存储库包含django的其他代码。
为什么我要创造这个?
因为我喜欢django,而且经常用它。但是,我发现一些基本的 现代web开发缺少代码。例如,您可能希望发送 ajax有效负载如下:
{"name":"John Doe","age":49,"email":"john@example.com","email_aliases":["john.due@example.com","due_49@example.com","john.1968@example.com"]}
在本例中,您可以使用Form
验证名称、年龄和电子邮件字段。
在Django层。但是,无法验证电子邮件别名,因为它是
列出并验证每个值是否为电子邮件格式。
为了支持这个案例(以及django无法处理的其他一些案例),我写道 一些支持列表验证的代码。
如何使用
表格
角形
如您所见,您需要实现冗余代码:
fromdjangoimportformsfrom.modelsimportUserInfoclassUserInfoForm(forms.ModelForm):classMeta(object):model=UserInfoexclude=("2fa_secret",)# They are already implemented because UserInfoForm inherit ModelForm# and the target model has the fields.widgets={"age":forms.NumberInput(attrs={"data-ng-model":"model.age"}),"phone":forms.TextInput(attrs={"data-ng-model":"model.phone"}),"street":forms.TextInput(attrs={"data-ng-model":"model.street"}),"city":forms.TextInput(attrs={"data-ng-model":"model.city"}),"state":forms.TextInput(attrs={"data-ng-model":"model.state"})}
但是,您可以通过使用AngularForm
:
fromdjangoimportformsfromdjextra.forms.angular1importAngularFormclassUserInfoForm(AngularForm,forms.ModelForm):ng_model_prefix="model"# Change this if you want to use other than "model"classMeta(object):model=UserInfoexclude=("2fa_secret",)# Automatically generates AngularJS forms.
angularjs和django之间的数据绑定
如果要在初始化时将值放入scope model,可以有两种方法:
- 使用
json.dumps
和django.forms.model_to_dict
- 设置
handle_ng_init
元属性
第一个很清楚,把你的模型转换成dict
django.forms.model_to_dict
,并将dict序列化为json,最后
将文本作为data-ng-init
放入如下表单:
<formdata-ng-init="model = {{ view.model_dict | tojson }}"><!-- bla bla bla bla... --></form>
第二个很简单;只需将表单的handle_ng_init
元属性设置为
True
像这样:
fromdjangoimportformsfromdjextra.forms.angular1importAngularFormclassUserInfoForm(AngularForm,forms.ModelForm):ng_model_prefix="model"# Change this if you want to use other than "model"handle_ng_init=TrueclassMeta(object):model=UserInfoexclude=("2fa_secret",)# Automatically generates AngularJS forms.
如果要指定要设置的值,可以使用ng_init_format_func
元属性如下:
fromdjangoimportformsfromdjextra.forms.angular1importAngularFormclassUserInfoForm(AngularForm,forms.ModelForm):ng_model_prefix="model"# Change this if you want to use other than "model"handle_ng_init=Trueng_init_format_func={"age":lambdavalue:f"{value} years old"}classMeta(object):model=UserInfoexclude=("2fa_secret",)# Automatically generates AngularJS forms.
但是,如您所知,服务器端与客户机端有很大不同,因此要
保持age
是格式化的,您可能还需要编写客户端代码。
所有必需的表格
如果您想使modelform上的所有字段都成为必需的,那么您将重新实现 整个字段如下:
fromdjangoimportformsfrom.modelsimportUserInfoclassUserInfoForm(forms.ModelForm):classMeta(object):model=UserInfoexclude=("2fa_secret",)# Assume that all fields are optional.age=forms.IntegerField(required=True,widget=forms.NumberInput(attrs={"data-ng-model":"model.age"}))phone=forms.CharField(required=True,widget=forms.TextInput(attrs={"data-ng-model":"model.phone"}))street=forms.CharField(required=True,widget=forms.TextInput(attrs={"data-ng-model":"model.street"}))city=forms.CharField(required=True,widget=forms.TextInput(attrs={"data-ng-model":"model.city"}))state=forms.CharField(required=True,widget=forms.TextInput(attrs={"data-ng-model":"model.state"}))
此外,除非您检查字段是否正确,否则您将无法检查字段是否正确
参考Django的代码。为了减少时间消耗,我实现了
AllReqiuredForm
:
fromdjangoimportformsfromdjextra.forms.angular1importAllRequiredFormfrom.modelsimportUserInfoclassUserInfoForm(AllRequiredForm,forms.ModelForm):classMeta(object):model=UserInfoexclude=("2fa_secret",)# Assume that all fields are optional.
通过使用AllRequiredForm
,您可以像上面那样减少loc。当然,
您可以将可选字段作为以下例外:
fromdjangoimportformsfromdjextra.forms.angular1importAllRequiredFormfrom.modelsimportUserInfoclassUserInfoForm(AllRequiredForm,forms.ModelForm):classMeta(object):model=UserInfoexclude=("2fa_secret",)# Assume that all fields are optional.# By specifying optional, the specified fields won't# become a required field.optional=("phone",)
字段属性窗体
当您设置属性时,特别是使用ModelForm
,您可能需要重新设置
具有widget
元属性的小部件,如下:
fromdjango.dbimportmodelsasdbfromdjangoimportformsclassNamePrice(db.Model):name=db.CharField()price=db.IntegerField()classNameDescForm(forms.ModelForm):classMeta(object):model=NamePriceexclude=("id",)widgets={"price":forms.NumberInput(attrs={"max":"100"})}
当您知道使用了什么小部件并且属性max
是
固定值。但是,如果您不知道使用了什么小部件,或者max
服务器django的动态值可能没有合适的解决方案。
为了解决这个问题,djetra有一个名为FieldAttributeForm
的表单
您可以这样使用:
fromdjango.dbimportmodelsasdbfromdjangoimportformsfromdjango.confimportsettingsclassNamePrice(db.Model):name=db.CharField()price=db.IntegerField()classNameDescForm(FieldAttributeForm,forms.ModelForm):classMeta(object):model=NamePriceexclude=("id",)fld_attrs={"price":{# The point is the attribute can be callable."max":lambdaform,fld,name,value:100ifvalueelse"","min":"0"},}
除此之外,FieldAttributeForm
还可以设置可以应用的属性
使用common_attrs
元属性对所有字段:
fromdjango.dbimportmodelsasdbfromdjangoimportformsfromdjango.confimportsettingsclassNamePrice(db.Model):name=db.CharField()price=db.IntegerField()classNameDescForm(FieldAttributeForm,forms.ModelForm):classMeta(object):model=NamePriceexclude=("id",)common_attrs={# Also it can be callable."data-on-delay":lambdaform,fld,name,value:(f"delay('{name}',{value})"),"data-on-load":"test()",}fld_attrs={"price":{"max":lambdaform,fld,name,value:100ifvalueelse"","min":0},}
表单域
列表字段
listfield用于处理值列表,如上面的示例所示。 要使用listfield,您可以编写这样的表单:
forms.py
fromdjangoimportformsfromdjextraimportformsasexformsclassExampleForm(forms.Form):name=forms.CharField()age=forms.IntegerField()email=forms.EmailField()email_aliases=exforms.ListField(field=forms.EmailField())
然后,像往常一样输入数据,验证就开始了。
如果不指定field
关键字参数,django.forms.CharField
对象
已指定。
小部件
角形材料的小部件
如果您喜欢Material Design,也可以使用Angular Material,但是
你可以看到医生。组件使用特殊标记。例如,
select
和option
输入控制器应替换为mdSelect
和
mdOption
并且它们不是由内置小部件提供的。
此小部件提供小部件:
fromdjangoimportformsfromdjextra.forms.angular1import(AngularForm,MDSelect,MDMultiSelect,MDDatePicker,MDDateSelect,MDCheckBox)from.modelsimportExampleModelclassExampleForm(AngularForm,forms.ModelForm):classMeta(object):model=ExampleModelexclude=("secret_field",)widgets={"start_since":MDDateSelect(),"available_date":MDDatePicker(),"shape":MDSelect(choices=(("F","Fat"),("N":"Normal"),("T","Thin"))),"needs_fill":MDCheckBox("Fill with border color?")}
贡献
代码的贡献是受欢迎的,并且代码是用tox测试的。以前 发送你的请求,请检查你测试你的代码非常好。
许可证
这个储存库是根据麻省理工学院的许可条款授权的。请检查一下 LICENSE.md获取详细信息。