Django框架基础(二)

MODELS

 1    对数据库起效的字段设置:
 2         数据类型:CharField
 3                   IntegerField
 4                   FloatField
 5                   DecimalField(max_digits=30,decimal_places=10)
 6                   DateTimeField
 7 
 8 
 9         字段参数:null=True  default=''   unique=True   db_index=True  premary_key
10         class Meta:
11         unique_together=(
12             ('email','ctime')
13         )
14         index_together=(
15             ('email','ctime')
16         )
17 
18    对admin起效的字段设置:
19          数据类型:
20                字符串:
21             EmailField(CharField):
22             IPAddressField(Field)
23             URLField(CharField)
24                     SlugField(CharField)
25             UUIDField(Field)
26             FilePathField(Field)
27             FileField(Field)
28             ImageField(FileField)
29             CommaSeparatedIntegerField(CharField)
30 
31                 枚举:
32                      color_list = (
33                     (1,'黑色'),
34                     (2,'白色'),
35                     (3,'蓝色')
36                         )
37              color = models.IntegerField(choices=color_list)
38                      应用场景:选项固定
39                                 
40              PS: FK选项动态
41          字段参数:
42                  verbose_name        Admin中显示的字段名称
43                  blank               Admin中是否允许用户输入为空
44                  editable            Admin中是否可以编辑
45                  help_text           Admin中该字段的提示信息
46                  choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
47                  test=models.CharField(
48                      max_length=32,
49                      error_messages={
50                         'c1':'优先错误信息'
51                            },
52                      validators=[RegexValidator(regex='root_d+',message='error',code='c1')],
53                      null=True
54     )
字段
 1 class Userinfo(models.Model):
 2     username=models.CharField(max_length=32)
 3     password=models.IntegerField(max_length=16)
 4 
 5     email=models.EmailField(null=True,default='1111',unique=True,blank=True,verbose_name='邮箱')
 6     ctime=models.DateTimeField(null=True)
 7     test=models.CharField(
 8         max_length=32,
 9         error_messages={
10             'c1':'优先错误信息'
11         },
12         validators=[RegexValidator(regex='root_d+',message='error',code='c1')],
13         null=True
14     )
15     color_list=(
16         (1,'black'),
17         (2,'white'),
18         (3,'blue'),
19     )
20     color=models.IntegerField(choices=color_list)
21 
22     class Meta:
23         unique_together=(
24             ('email','ctime')
25         )
26         index_together=(
27             ('email','ctime')
28         )
View Code

 详细见下方补充信息

ORM数据表多对多操作:

1 自定义第三张表:

 1     class Gril(models.Model):
 2     nick=models.CharField(max_length=64)
 3 
 4 
 5     class Boy(models.Model):
 6     name=models.CharField(max_length=64)
 7 
 8     class Love(models.Model):
 9     b=models.ForeignKey('Boy')
10     g=models.ForeignKey('Gril')
11     class Meta:    #设置联合唯一索引
12         unique_together=[
13             ('b','g'),
14         ]
15 
16  查询和Alex1 有关系的姑娘
17         obj=models.Boy.objects.filter(name='alex1').first()
18         love_list=obj.love_set.all()
19         for row in love_list:
20             print(row.g.nick)
21 
22         love_list=models.Love.objects.filter(b__name='alex1')
23         for row in love_list:
24             print(row.g.nick)
25 
26         love_list=models.Love.objects.filter(b__name='alex1').values('g__nick')
27         for item in love_list:
28             print(item['g__nick'])
29 
30         love_list=models.Love.objects.filter(b__name='alex1').select_related('g')
31         for obj in love_list:
32             print(obj.g.nick)
View Code

2 Django自动生成关系表:

 1 class Gril(models.Model):
 2     nick=models.CharField(max_length=64)
 3     m=models.ManyToManyField('Boy')               #Django内置的多对多连表设置
 4 
 5 django 内置的多对多连表操作,不能直接对连表进行操作,可以间接操作
 6         # obj=models.Gril.objects.filter(nick='egon1').first()
 7         # print(obj.nick,obj.id)
 8         # obj.m.add(2)
 9         # obj.m.add(2,4)
10         # obj.m.add(*[1,])
11 
12         # obj.m.remove(1)
13         # obj.m.remove(*[2,4])
14         # obj.m.set([1,])
15 
16         # q=obj.m.all()
17         # print(q)     #<QuerySet [<Boy: Boy object>]>
18         #
19         # boy_list=obj.m.filter(name='alex1').first()
20         # print(boy_list.name)
21 
22         # obj=models.Gril.objects.filter(nick='egon1').first()
23         # obj.m.clear()
24         #反向操作
25         # obj=models.Boy.objects.filter(name='alex1').first()
26         # v=obj.gril_set.all()
27         # print(v)
View Code

3杂交:

 1                         class Boy(models.Model):
 2                 name = models.CharField(max_length=32)
 3                 m = models.ManyToManyField('Girl',through="Love",through_fields=('b','g',))
 4                 # 查询和清空
 5 
 6             class Girl(models.Model):
 7                 nick = models.CharField(max_length=32)
 8                 # m = models.ManyToManyField('Boy')
 9 
10             class Love(models.Model):
11                 b = models.ForeignKey('Boy')
12                 g = models.ForeignKey('Girl')
13 
14                 class Meta:
15                     unique_together = [
16                         ('b','g'),
17                     ]
View Code

4 自关联   自定义第三张表:

 1 class UserInfo(models.Model):
 2     nickname=models.CharField(max_length=64)
 3     username=models.CharField(max_length=64)
 4     password=models.CharField(max_length=64)
 5     gender_choice=(
 6         (1,''),
 7         (2,''),
 8     )
 9     gender=models.IntegerField(choices=gender_choice)
10 
11 class U2U(models.Model):
12     g=models.ForeignKey(to='UserInfo',to_field='id',related_name='boys')
13     b=models.ForeignKey(to='UserInfo',to_field='id',related_name='grils')
View Code
1     xz=models.UserInfo.objects.filter(id=1).first()
2     result=xz.gril.all()
3     for u in result:
4         print(u.g.nickname)
View Code

 

 5 自关联   自动生产第三张表:

 1 class UserInfo(models.Model):
 2     nickname=models.CharField(max_length=64)
 3     username=models.CharField(max_length=64)
 4     password=models.CharField(max_length=64)
 5     gender_choice=(
 6         (1,''),
 7         (2,''),
 8     )
 9     gender=models.IntegerField(choices=gender_choice)
10     m=models.ManyToManyField('UserInfo')
View Code
 1     # 查男生
 2     xz = models.UserInfo.objects.filter(id=1).first()
 3     u = xz.m.all()
 4     for row in u:
 5         print(row.nickname)
 6     # 查女神
 7     xz = models.UserInfo.objects.filter(id=4).first()
 8     v = xz.userinfo_set.all()
 9     for row in v:
10         print(row.nickname)
11     return HttpResponse('...')
View Code

 

6 FK 自关联

 1 class Comment(models.Model):
 2     """
 3     评论表
 4     """
 5     news_id = models.IntegerField()            # 新闻ID
 6     content = models.CharField(max_length=32)  # 评论内容
 7     user = models.CharField(max_length=32)     # 评论者
 8     reply = models.ForeignKey('Comment',null=True,blank=True,related_name='xxxx')
 9 """
10    新闻ID                         reply_id
11 1   1        别比比    root         null
12 2   1        就比比    root         null
13 3   1        瞎比比    shaowei      null
14 4   2        写的正好  root         null
15 5   1        拉倒吧    由清滨         2
16 6   1        拉倒吧1    xxxxx         2
17 7   1        拉倒吧2    xxxxx         5
18 """
19 """
20 新闻1
21     别比比
22     就比比
23         - 拉倒吧
24             - 拉倒吧2
25         - 拉倒吧1
26     瞎比比
27 新闻2:
28     写的正好
29 """
View Code

 

 admin

django amdin是django提供的一个后台管理页面,改管理页面提供完善的html和css,使得你在通过Model创建完数据库表之后,就可以对数据进行增删改查,而使用django admin 则需要以下步骤:

  • 创建后台管理员
  • 配置url
  • 注册和配置django admin后台管理页面

1、创建后台管理员

1
python manage.py createsuperuser

2、配置后台管理url

1
url(r'^admin/', include(admin.site.urls))

3、注册和配置django admin 后台管理页面

 a、在admin中执行如下配置

1 from django.contrib import admin
2   
3 from app01 import  models
4   
5 admin.site.register(models.UserType)
6 admin.site.register(models.UserInfo)
7 admin.site.register(models.UserGroup)
8 admin.site.register(models.Asset)
View Code

 b、设置数据表名称

1 class UserType(models.Model):
2     name = models.CharField(max_length=50)
3   
4     class Meta:
5         verbose_name = '用户类型'
6         verbose_name_plural = '用户类型'
View Code

 c、打开表之后,设定默认显示,需要在model中作如下配置

 1 from django.contrib import admin
 2   
 3 from app01 import  models
 4   
 5 class UserInfoAdmin(admin.ModelAdmin):
 6     list_display = ('username', 'password', 'email')
 7   
 8   
 9 admin.site.register(models.UserType)
10 admin.site.register(models.UserInfo,UserInfoAdmin)
11 admin.site.register(models.UserGroup)
12 admin.site.register(models.Asset)
View Code

 d、为数据表添加搜索功能

 1 from django.contrib import admin
 2   
 3 from app01 import  models
 4   
 5 class UserInfoAdmin(admin.ModelAdmin):
 6     list_display = ('username', 'password', 'email')
 7     search_fields = ('username', 'email')
 8   
 9 admin.site.register(models.UserType)
10 admin.site.register(models.UserInfo,UserInfoAdmin)
11 admin.site.register(models.UserGroup)
12 admin.site.register(models.Asset)
View Code

 e、添加快速过滤

 1 from django.contrib import admin
 2   
 3 from app01 import  models
 4   
 5 class UserInfoAdmin(admin.ModelAdmin):
 6     list_display = ('username', 'password', 'email')
 7     search_fields = ('username', 'email')
 8     list_filter = ('username', 'email')
 9       
10   
11   
12 admin.site.register(models.UserType)
13 admin.site.register(models.UserInfo,UserInfoAdmin)
14 admin.site.register(models.UserGroup)
15 admin.site.register(models.Asset)
View Code

ajax请求

新url的方式:
点击---href跳转页面---对应函数(GET请求)---返回另一个html文件
---增加或编辑---form表单提交数据--函数中数据库更新(POST请求)---重定向

当客户端的添加或编辑按钮不经常使用时,没必要在页面开始加载时就将内容写入模态对话框,只需要在点击时触发一个ajax请求就可以获取数据
服务端接收ajax请求一般要进行try,except捕捉异常

为了防止读取数据库时间过长,用户体验不好,加上‘正在加载’的图片


模态对话框的方式:
点击---触发js事件---显示对话框(对话框中标签的内容可以是刚开始加载时就写好的,也可以是点击之后通过ajax请求得到的)
---增加或编辑---发送ajax请求---对应函数,更新数据库(POST请求)---返回字典---重新加载或报错

 

ajax请求:利用模态对话框处理浏览器请求时,为了防止form表单提交数据时自动刷新页面,采用ajax向后端发送数据
前端不会发生任何变化,数据处理结束后,后端给ajax返回一个字典,ajax根据字典来进行重新加载或报错

 1 $.ajax({
 2         url:'', #数据提交的地址
 3         type: 'get/post',
 4         data: {'key1':value,'key2':[],'k3': JSON.stringify({k1:v1,...}}, #要发送的数据,可以是字符串或列表
 5    dataType: 'JSON', #相当于json.parse(data) 将json字符串反序列化为jquery对象
 6    traditional:true, #如果ajax提交的数据有列表,则要加上traditional:true,
 7    success:function(data){
 8           if(data.status){
 9      location.reload('') #重新加载某页面
10 
11                location.href('/index.html?page=')+data.id   #利用ajax进行重定向
12       }else{
13       alert(data.message)} 
14       })
View Code

 中间件

django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法。

在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件,如下图。

与mange.py在同一目录下的文件夹 wupeiqi/middleware下的auth.py文件中的Authentication类

中间件中可以定义四个方法,分别是:

  • process_request(self,request)
  • process_view(self, request, callback, callback_args, callback_kwargs)
  • process_template_response(self,request,response)
  • process_exception(self, request, exception)
  • process_response(self, request, response)

以上方法的返回值可以是None和HttpResonse对象,如果是None,则继续按照django定义的规则向下执行,如果是HttpResonse对象,则直接将该对象返回给用户。

自定义中间件

1、创建中间件类

1
2
3
4
5
6
7
8
9
10
11
12
class RequestExeute(object):
      
    def process_request(self,request):
        pass
    def process_view(self, request, callback, callback_args, callback_kwargs):
        =1
        pass
    def process_exception(self, request, exception):
        pass
      
    def process_response(self, request, response):
        return response

2、注册中间件

1
2
3
4
5
6
7
8
9
10
MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'wupeiqi.middleware.auth.RequestExeute',

 补充信息:

    AutoField(Field)
        - int自增列,必须填入参数 primary_key=True

    BigAutoField(AutoField)
        - bigint自增列,必须填入参数 primary_key=True

        注:当model中如果没有自增列,则自动会创建一个列名为id的列
        from django.db import models

        class UserInfo(models.Model):
            # 自动创建一个列名为id的且为自增的整数列
            username = models.CharField(max_length=32)

        class Group(models.Model):
            # 自定义自增列
            nid = models.AutoField(primary_key=True)
            name = models.CharField(max_length=32)

    SmallIntegerField(IntegerField):
        - 小整数 -32768 ~ 32767

    PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正小整数 0 ~ 32767
    IntegerField(Field)
        - 整数列(有符号的) -2147483648 ~ 2147483647

    PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
        - 正整数 0 ~ 2147483647

    BigIntegerField(IntegerField):
        - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807

    自定义无符号整数字段

        class UnsignedIntegerField(models.IntegerField):
            def db_type(self, connection):
                return 'integer UNSIGNED'

        PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
            'AutoField': 'integer AUTO_INCREMENT',
            'BigAutoField': 'bigint AUTO_INCREMENT',
            'BinaryField': 'longblob',
            'BooleanField': 'bool',
            'CharField': 'varchar(%(max_length)s)',
            'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
            'DateField': 'date',
            'DateTimeField': 'datetime',
            'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
            'DurationField': 'bigint',
            'FileField': 'varchar(%(max_length)s)',
            'FilePathField': 'varchar(%(max_length)s)',
            'FloatField': 'double precision',
            'IntegerField': 'integer',
            'BigIntegerField': 'bigint',
            'IPAddressField': 'char(15)',
            'GenericIPAddressField': 'char(39)',
            'NullBooleanField': 'bool',
            'OneToOneField': 'integer',
            'PositiveIntegerField': 'integer UNSIGNED',
            'PositiveSmallIntegerField': 'smallint UNSIGNED',
            'SlugField': 'varchar(%(max_length)s)',
            'SmallIntegerField': 'smallint',
            'TextField': 'longtext',
            'TimeField': 'time',
            'UUIDField': 'char(32)',

    BooleanField(Field)
        - 布尔值类型

    NullBooleanField(Field):
        - 可以为空的布尔值

    CharField(Field)
        - 字符类型
        - 必须提供max_length参数, max_length表示字符长度

    TextField(Field)
        - 文本类型

    EmailField(CharField):
        - 字符串类型,Django Admin以及ModelForm中提供验证机制

    IPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制

    GenericIPAddressField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
        - 参数:
            protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
            unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"

    URLField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证 URL

    SlugField(CharField)
        - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)

    CommaSeparatedIntegerField(CharField)
        - 字符串类型,格式必须为逗号分割的数字

    UUIDField(Field)
        - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证

    FilePathField(Field)
        - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
        - 参数:
                path,                      文件夹路径
                match=None,                正则匹配
                recursive=False,           递归下面的文件夹
                allow_files=True,          允许文件
                allow_folders=False,       允许文件夹

    FileField(Field)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage

    ImageField(FileField)
        - 字符串,路径保存在数据库,文件上传到指定目录
        - 参数:
            upload_to = ""      上传文件的保存路径
            storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
            width_field=None,   上传图片的高度保存的数据库字段名(字符串)
            height_field=None   上传图片的宽度保存的数据库字段名(字符串)

    DateTimeField(DateField)
        - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]

    DateField(DateTimeCheckMixin, Field)
        - 日期格式      YYYY-MM-DD

    TimeField(DateTimeCheckMixin, Field)
        - 时间格式      HH:MM[:ss[.uuuuuu]]

    DurationField(Field)
        - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型

    FloatField(Field)
        - 浮点型

    DecimalField(Field)
        - 10进制小数
        - 参数:
            max_digits,小数总长度
            decimal_places,小数位长度

    BinaryField(Field)
        - 二进制类型
字段
    null                数据库中字段是否可以为空
    db_column           数据库中字段的列名
    db_tablespace
    default             数据库中字段的默认值
    primary_key         数据库中字段是否为主键
    db_index            数据库中字段是否可以建立索引
    unique              数据库中字段是否可以建立唯一索引
    unique_for_date     数据库中字段【日期】部分是否可以建立唯一索引
    unique_for_month    数据库中字段【月】部分是否可以建立唯一索引
    unique_for_year     数据库中字段【年】部分是否可以建立唯一索引

    verbose_name        Admin中显示的字段名称
    blank               Admin中是否允许用户输入为空
    editable            Admin中是否可以编辑
    help_text           Admin中该字段的提示信息
    choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
                        如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)

    error_messages      自定义错误信息(字典类型),从而定制想要显示的错误信息;
                        字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
                        如:{'null': "不能为空.", 'invalid': '格式错误'}

    validators          自定义错误验证(列表类型),从而定制想要的验证规则
                        from django.core.validators import RegexValidator
                        from django.core.validators import EmailValidator,URLValidator,DecimalValidator,
                        MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
                        如:
                            test = models.CharField(
                                max_length=32,
                                error_messages={
                                    'c1': '优先错信息1',
                                    'c2': '优先错信息2',
                                    'c3': '优先错信息3',
                                },
                                validators=[
                                    RegexValidator(regex='root_d+', message='错误了', code='c1'),
                                    RegexValidator(regex='root_112233d+', message='又错误了', code='c2'),
                                    EmailValidator(message='又错误了', code='c3'), ]
                            )
参数
    class UserInfo(models.Model):
        nid = models.AutoField(primary_key=True)
        username = models.CharField(max_length=32)
        class Meta:
            # 数据库中生成的表名称 默认 app名称 + 下划线 + 类名
            db_table = "table_name"

            # 联合索引
            index_together = [
                ("pub_date", "deadline"),
            ]

            # 联合唯一索引
            unique_together = (("driver", "restaurant"),)

            # admin中显示的表名称
            verbose_name

            # verbose_name加s
            verbose_name_plural
        
    更多:https://docs.djangoproject.com/en/1.10/ref/models/options/
元信息
    1.触发Model中的验证和错误提示有两种方式:
        a. Django Admin中的错误信息会优先根据Admiin内部的ModelForm错误信息提示,如果都成功,才来检查Model的字段并显示指定错误信息
        b. 调用Model对象的 clean_fields 方法,如:
            # models.py
            class UserInfo(models.Model):
                nid = models.AutoField(primary_key=True)
                username = models.CharField(max_length=32)

                email = models.EmailField(error_messages={'invalid': '格式错了.'})

            # views.py
            def index(request):
                obj = models.UserInfo(username='11234', email='uu')
                try:
                    print(obj.clean_fields())
                except Exception as e:
                    print(e)
                return HttpResponse('ok')

           # Model的clean方法是一个钩子,可用于定制操作,如:上述的异常处理。

    2.Admin中修改错误提示
        # admin.py
        from django.contrib import admin
        from model_club import models
        from django import forms


        class UserInfoForm(forms.ModelForm):
            username = forms.CharField(error_messages={'required': '用户名不能为空.'})
            email = forms.EmailField(error_messages={'invalid': '邮箱格式错误.'})
            age = forms.IntegerField(initial=1, error_messages={'required': '请输入数值.', 'invalid': '年龄必须为数值.'})

            class Meta:
                model = models.UserInfo
                # fields = ('username',)
                fields = "__all__"


        class UserInfoAdmin(admin.ModelAdmin):
            form = UserInfoForm


        admin.site.register(models.UserInfo, UserInfoAdmin)
拓展知识
原文地址:https://www.cnblogs.com/liuguniang/p/7105911.html