多对多三种创建方式
方式一:全自动
'''
class Book(models.Model):
title = models.CharField(max_length=32)
authors = models.ManyToManyField(to='Author')
class Author(models.Model):
name = models.CharField(max_length=32)
好处:至始至终你都没有操作第三张表 全部都是由orm自动帮你创建的还内置了四个操作第三张表的方法
add,remove,set,clear
不足:
自动创建第三张表,无法扩展和修改字段,表的扩展性比较差
'''
方式二:手撸(了解)
'''
class Book(models.Model):
title = models.CharField(max_length=32)
class Authors(models.Model):
name = models.CharField(max_length=32)
class Book2Authors(models.Model):
book = models.ForeignKey(to="Book")
author = models.ForeignKey(to="Authors")
create_time = models.DateField(auto_now_add = True)
好处:第三张表中字段个数和字段名称全都可以自己定义
不足:不再支持orm跨表查询 不再由正反向的概念
add,remove,set,clear
'''
方式三:半自动(推荐使用)
'''
class Book(models.Model):
titile=models.CharField(max_length=32)
author=models.ManyToManyField(to='Author',throuth='Book2Author',
throuth_fields=('book','author'))
class Authors(models.Model):
name = models.CharField(max_length=32)
# 多对多关系字段 等价
books = models.ManyToManyField(to='Book', through='Book2Author', through_fields=("authors","book"))
class Book2Author(models.Model):
book = models.ForeignKey(to='Book')
authors = models.ForeignKey(to='Authors')
参数:
throuth:用来绑定第三张表
throuth_fields:用于指出与第三张表中哪两个字段来记录的
好处:可以任意的添加和修改第三张表中的字段,并且支持orm跨表查询
不足:不支持add,remove,clrar,set
'''
'''
使用form组件的前提是你需要先提前写一个类
cleaned_data:所有校验通过的数据
is_valid:判断传的值是否有效
errors:查看错误的字段信息
'''
from django import forms
class MyForm(forms.Form):
usernmae=forms.CharField(max_length=8,min_length=3,lable='用户名',initial='默认值',error_message={
'max_length':'用户名最长八位',
'min_length':'用户名最短三位'
'required':'用户名不能为空'
},
required=False, # 设置允许为空
widget=forms.widgets.TextdInput({'class':'form-control'}) # 设置class
)
password=forms.CharField(max_leng=8,min_length=3,lable='密码',
error_message={
'max_length':'用户名最长八位',
'min_length':'用户名最短三位'
'required':'用户名不能为空'
},
widget=forms.widgets.PasswordInput() # 设置为密文
)
email=forms.EmailField(lable='邮箱',error_message={
'required':'邮箱不能为空'
'invalid':'邮箱格式错误'
})
gender = forms.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性别",
initial=3,
widget=forms.widgets.RadioSelect()
)
hobby = forms.ChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=3,
widget=forms.widgets.Select()
)
hobby1 = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.SelectMultiple()
)
keep = forms.ChoiceField(
label="是否记住密码",
initial="checked",
widget=forms.widgets.CheckboxInput()
)
hobby2 = forms.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.CheckboxSelectMultiple()
)
# 校验用户名中不能含有666 局部钩子
def clean_username(self):
username = self.cleaned_data.get('username')
if '666' in username:
# 给username所对应的框展示错误信息
# self.add_error('username','光喊666是不行的')
raise ValidationError('到底对不对啊')
# 将username数据返回
return username
# 校验密码 确认密码是否一致 全局钩子
def clean(self):
password = self.cleaned_data.get("password")
confirm_password = self.cleaned_data.get("confirm_password")
if not password == confirm_password:
self.add_error('confirm_password','两次密码不一致')
# 将全局的数据返回
return self.cleaned_data
def index(request):
# 渲染标签 第一步 需要生成一个空的forms类的对象
forms_obj=MyForm()
if request_method=='POST':
forms_obj=MyForm(request.POST)
if froms_obj.is_valid():
return HttpResponse('OK')
return render(request,'index.html',locals())