• Django基础学习笔记


    开始

    1.创建项目:

    django-admin startproject mysite 
    

    2.创建app

    cd mysite
    python manage.py startapp cmdb
    

    3.运行

    python manage.py runserver 
    

    目录结构与用途

    mysite
        - mysite  项目配置
            - __init__
            - settings  配置文件
            - url       url路由配置
            - wsgi      遵循wsgi规范,上线uwsgi+nginx
            - manage.py     管理Django程序
    
        app:
            - migrations 数据库表结构修改记录
            - admin Django为我们的app程序自动创建的后台管理
            - apps 对当前app的配置
            - models 数据库orm,写指定的class,通过命令创建数据库结构
            - tests 单元测试
            - views app相关的所有业务,业务逻辑
    

    配置

    1.使用模板文件

    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')],   ##新加
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    

    2.静态文件配置

    STATIC_URL = '/static/'
    STATICFILES_DIRS = (
        os.path.join(BASE_DIR, 'static'),
    )
    # TEMPLATE_DIRS = (os.path.join(BASE_DIR,  'templates'),)
    
    

    3.暂时停止POST跨站请求伪造

    
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        #'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
    ]
    
    

    路由规则设定

    • FBV
    from cmdb import views  # 在app中导入视图函数
     # Django会默认添加/,此处url路由写的什么,html的form表单中action也必须相同
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^login', views.login),  
        url(r'^home', views.home),
    ]
    
    • CBV
    from mytest import views
     
    urlpatterns = [
        url(r‘^index/‘, views.Index.as_view()),
    ]
    

    views视图函数:

    • 形参:request client发送过来的各种信息
    request.POST 
    request.GET
    request.methed 为POST或者GET
    
    • 值获取举例
     # 单个值
    request.POST.get("key",None) 
    request.GET.get("key",None)
    
     # 多个值,返回一个list
    request.GET.getlist("key",None)
    request.POST.getlist("key",None)
    

    视图函数返回

    • 页面返回
    1. render 返回一个完整的html页面
    2. HttpResponse 返回字符串
    3. redirect 重定向,跳转动作不是在后台做的,不能写html模板路径
    • 返回举例
    return render(request, 'login.html', {"error_msg": error_msg})  模板中通过key来获取,返回必须为一个字典,字典简直对适量不限制
    return redirect("http://www.baidu.com")  # 重定向
    return redirect("/home")  # 重定向
    return HttpResponse("string")
    

    模板渲染:

    • 循环
    	{% for row in user_list %} 
            <tr>
                <td>{{ row.username }}</td>  获得字典key对应的值
                <td>{{ row.gender }}</td>
                <td>{{ row.email }}</td>
            </tr>
        {% endfor %}
    
    • 值获取:索引
    eg:
        return render(request, 'login.html', {"info": "Leon","user_list":[1,2,3,4,5],"user_dict":{"k1":"v1","k2":"v2"},}) 
    
    列表或字典获取值:
        {{ user_list.0 }}
        {{ user_list.1 }}
        {{ user_dict.k1 }}
        {{ user_dict.k2 }}
    
    • 条件判断
        {% if info %}
        	{% if user_list.0 > 18 %}
        		<a>old</a>
        	{% else %}
        		<a>young</a>	
        	{% endif %}
        	<a>用户为:info</a>
        {% else %}	
        	<a>用户为空</a>
        {% endif %}
    

    html数据提交

    1. 单选框,name相同,value不同,才可以区分开,单个值用get可以获取
    2. 复选框,name相同,value不同,多个用getlist获取,得到一个列表
    3. select,select只有一个name,option中的value不同,多选在select中设定:multiple="multiple",后端依然使用getlist获取
    
    
    4. 文件上传 :
    
    前端:form表单中新增属性:enctype=“multipart/form-data”
    后端:使用 obj = request.FILES,get(name) 来获取文件数据句柄
        import os
        file_path = os.path.join('upload',obj.name)
        f = open(file_path,mode='wb')
        for i in obj.chunks():
            f.write(i)
        f.close()
    
    

    FBV和CBV

    • urls中的区别在上面
    • 视图函数写法:
    from django.views import View
     
    class Index(View):  # 必须继承View
    
        # 链接进来首先调用的是dispatch方法
        def dispatch(self, request, *args, **kwargs):  # dispatch使用了类似反射的方法,来区分get、post
            # 调用父类中的dispatch
            print(‘before‘)  # 类似装饰器的功能
            result = super(Home,self).dispatch(request, *args, **kwargs)
            print(‘after‘)  # 类似装饰器的功能
            return result
    
        def get(self, req):
            print(‘method is :‘ + req.method)
            return render(req, ‘index.html‘)
     
        def post(self, req):
            print(‘method is :‘ + req.method)
            return render(req, ‘index.html‘)
    

    路由系统url

    1. 基本设定

    url(r'^index/', views.index),   # FBV
    url(r'^home/', views.Home.as_view()), CBV
    

    2. 正则匹配之无指定参数

    url(r'^detail-(d+).html', views.detail), 
    
    # 举例
    url(r'^detail-(d+)-(d+).html', views.detail),
    位置参数接收:前后对应
    def func(request, nid, uid):
    通用参数接收:都在args里
    def func(request, *args):
    def func(request, *args, **kwargs):
    

    3. 有指定参数

    url(r'^detail-(?P<nid>d+)-(?P<uid>d+).html', views.detail)
    
    # 举例
    url(r'^detail-(?P<nid>d+)-(?P<uid>d+).html', views.detail)
    指定参数接收:
    def func(request, nid, uid):
    def func(request, nid, uid):
    通用参数接收:
    def funct(request, **kwargs):
        kwargs = {'nid': 1, 'uid': 3}
    

    4. name 可以根据此名称生成自己想要的URL

    # urls设定
    
    url(r'^asdfasdfasdf/', views.index, name='i1'),
    url(r'^yug/(d+)/(d+)/', views.index, name='i2'),
    url(r'^buy/(?P<pid>d+)/(?P<nid>d+)/', views.index, name='i3'),
    		
    		
    # views函数设定	
    def func(request, *args, **kwargs):
        from django.urls import reverse
    			
        url1 = reverse('i1')                              # asdfasdfasdf/
        url2 = reverse('i2', args=(1,2,))                 # yug/1/2/
        url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # buy/1/9/
    		
    # 模板中设定
    xxx.html
    			
        {% url "i1" %}               # asdfasdfasdf/
        {% url "i2" 1 2 %}           # yug/1/2/
        {% url "i3" pid=1 nid=9 %}   # buy/1/9/
    		
    # 注:
    # 当前的URL
        request.path_info
    
    

    5. 多级路由 app区分,多个app并行开发

    • 项目主路由设定,分发到各个app
    project/urls.py
        from django.conf.urls import url,include
            urlpatterns = [
                url(r'^cmdb/', include("app01.urls")),
                url(r'^monitor/', include("app02.urls")),
            ]
    
    app01/urls.py
        from django.conf.urls import url
        from app01 import views
            urlpatterns = [
                url(r'^login/', views.login),
            ]
    

    6.默认值

    
    

    7.命名空间

    
    

    django-orm

    Django默认使用的为sqlite,所以在使用mysql的时候需要对其进行相关设定

    1.settings.py

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME':'dbname',
            'USER': 'root',
            'PASSWORD': 'xxx',
            'HOST': '',
            'PORT': '',
        }
    }
    

    2. project项目下的__init__.py

    由于Django默认使用MySQLdb,python3中无此模块,使用pymysql的话需要再次添加:
        import pymysql
        pymysql.install_as_MySQLdb()
    

    3. 在settings中INSTALLED_APPS注册我们的app

    4.app的models.py中创建表

    from django.db import models
    # Create your models here.
    class UserInfo(models.Model):
        # django会默认帮你创建一个自增id字段作为主键
        username = models.CharField(max_length=32)
        password = models.CharField(max_length=64)
        email = models.EmailField()
    

    5. makemigrations

    python manage.py makemigrations
    创建更改的文件
    

    6.migrate

    python manage.py migrate
    将生成的py文件应用到数据库
    
    

    7. 生成的表:

    +----------------------------+
    | Tables_in_cmdb             |
    +----------------------------+
    | app_cmdb_userinfo          |
    | auth_group                 |
    | auth_group_permissions     |
    | auth_permission            |
    | auth_user                  |
    | auth_user_groups           |
    | auth_user_user_permissions |
    | django_admin_log           |
    | django_content_type        |
    | django_migrations          |
    | django_session             |
    +----------------------------+ 
    
    mysql> desc app_cmdb_userinfo;
    +----------+--------------+------+-----+---------+----------------+
    | Field    | Type         | Null | Key | Default | Extra          |
    +----------+--------------+------+-----+---------+----------------+
    | id       | int(11)      | NO   | PRI | NULL    | auto_increment |
    | username | varchar(32)  | NO   |     | NULL    |                |
    | password | varchar(64)  | NO   |     | NULL    |                |
    | email    | varchar(254) | NO   |     | NULL    |                |
    +----------+--------------+------+-----+---------+----------------+
    
    

    Django ORM操作相关

    1.添加数据

    from app_cmdb import models
    # 有几个字段,传几个参数就行了
    models.UserInfo.objects.create(username="leon", password="123123", email='4641231@qq.com')
    
    # 方法2
    stu1 = user(username="leon", password="123123", email='4641231@qq.com')
    stu1.save() # flush到数据库中
    

    2.数据修改

    # 单个数据的多个字段同时跟新
    models.UserInfo.objects.get(username="leon", password="123123", email='4641231@qq.com').update(username="Leon",password="qweasdC")
    
    # 跟新某个字段
    user_obj = models.UserInfo.objects.get(username="leon", password="123123")
    user_obj.username="Jack"
    user_obj.save()
    
    # 多条数据同时跟新
    models.UserInfo.objects.all().update(username='Zhang') 
    

    3.数据删除

    # 删除表中所有数据
    models.UserInfo.objects.all().delete()
    # 筛选单个删除
    models.UserInfo.objects.get(username="leon").delete()
    # 过滤多个删除
    models.UserInfo.objects.filter(username="leon").delete()
    
    

    4.数据查询,所有查询、过滤、排序、取值方法可以结合自己的使用场景来使用,以达到最佳的效果

    # 查询所有记录
    models.UserInfo.objects.all()
    
    
    # 带字段名的所有记录,就是将所有记录以key-value的形式保存在字典中
    models.UserInfo.objects.all().values()
    >>><QuerySet [{'id': 1, 'username': 'leon', 'password': '123123', 'email': '4641231@qq.com'}, {'id': 2, 'username': 'leon', 'password': '1123123', 'email': '4641231@qq.com'}]>
    
    # 查询单条记录,使用get查询单条数据,如果没有查到,会直接报错,结合try来使用
    models.UserInfo.objects.get(name='Aaron')
    
    # 查询多条中的第一条记录,多个过滤条件,需要在filter中用逗号分隔开
    models.UserInfo.objects.filter(username='leon', password="123123").first()
    
    # 模糊过滤,字段只要包含就可以
    models.UserInfo.objects.filter(username__contains='leo').first()
    
    # 模糊-不区分大小写
    models.UserInfo.objects.filter(username__icontains='leo').first()
    
    
    # 将字段内容排序后显示
    models.UserInfo.objects.order_by('username')
    
    
    # 查询记录的个数
    models.UserInfo.objects.filter().conut()
    
    # 筛选之大于小于,多个用逗号分开
    models.UserInfo.objects.filter(id__gt=1)  # 大于1
    models.UserInfo.objects.filter(id__gte=1)  # 大于等于1
    models.UserInfo.objects.filter(id__lt=1)  # 小于1
    models.UserInfo.objects.filter(id__lte=1)  # 小于等于1
    models.UserInfo.objects.filter(id_gt=1,id__lte=10) # 大于1小于等于10
    
    
    # in,not in
    models.UserInfo.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
    models.UserInfo.objects.exclude(id__in=[11, 22, 33])  # not in
    
    
    # 排序值逆序
    models.UserInfo.objects.order_by('-username')
    
    # 限制数据条数,因为返回的是一个QuerySet类型的列表,我们可以使用列表的分片来获取想要的数据内容,依然按照`顾首不顾尾`的原则
    models.UserInfo.objects.filter(username="leon")[0]  # 第一条数据
    models.UserInfo.objects.filter(username="leon")[0:3]  # 去前三条数据
    
    
    

    5.数据字段类型

    • 几种主要的类型之-数字类型
    1. AutoField int类型(1 to 2147483647)的自增id列,须加参数 primary_key=True
    2. BigAutoField bigint类型(1 to 9223372036854775807),同上
    3. BigIntegerField
    4. IntegerField
    5. FloatField 
    6. SmallIntegerField
    7. PositiveIntegerField
    8. PositiveSmallIntegerField
    
    
    • 字符串类型
    1. CharField
    2. EmailField (admin)
    3. GenericIPAddressField (admin)
    4. URLField (admin)
    5. UUIDField
    
    
    • 时间类型
    1. DateField (Python:datetime.date)
    2. DateTimeField (Python: datetime.datetime )
    3. DecimalField (python : Decimal)
    4. DurationField (python :  timedelta)
    5. TimeField  (python : datetime.time)
    
    
    • 二进制类型
    1. BinaryField
    
    • 布尔类型
    1. BooleanField
    
    • 文件类型
    1. FileField
    

    6.参数

    • 基本
    - null 是否可以为空
    - default 默认值
    - primary_key 主键
    - db_column 舍子数据库中的列名
    - db_index  建立普通索引
    - unique 唯一索引
    - unique_for_data 只对时间做索引
    - unique_for_month 只对月份做索引
    - unique_for_year 只对年份做索引
    - auto_now  添加还是修改对象,时间为你添加或者修改的时间,需要使用obj.save()来跟新,而update不能跟新
    - auto_now_add 创建时自动创建时间,跟新不动
    
    
    • admin:
    
    - choices 两个作用
    	user_type_choices = (  # 将这些字段放进内存,而避免数据库连表操作
            (1,'root'),
            (2,'root1'),
            (3,'root1')
        ) 而且在django-admin中可以通过select直接选择
        user_type_id = models.IntegerField(choices=user_type_choices,default=1)
    - blank admin中是否可以为空
    - verbose_name="用户名"  前端显示的别名
    - editable 是否可以被编辑
    - error_messages 输入错误提示消息自定义   error_messages={'required':u'邮箱不能为空'}????
    - help_text help_text="user_name"  输入框下的用户提示信息
    - validators  Django的form自定义验证机制设置
    

    7.外键的连表操作

    • 表结构
    class Host(models.Model):
        nid = models.AutoField(primary_key=True)
        hostname = models.CharField(max_length=32, db_index=True)
        ip = models.GenericIPAddressField(db_index=True, protocol='ipv4')
        port = models.IntegerField()
        b = models.ForeignKey(to='Business', to_field='id')
    
    
    class Business(models.Model):
        caption = models.CharField(max_length=32)
        code = models.CharField(max_length=32)
    

    1.单表三种获取方式

    # QuerySet内部为对象,模板获取的时候用"."来获取
    v1 = models.Business.objects.all() 
    
    
    # QuerySet内部为key、value的字典,因为是字典,在模板中获取的时候用"."来获取,
    v2 = models.Business.objects.all().values('id', 'caption')  #只获取特定字段
    
    # QuerySet内部为元组,因为是元组,在模板中获取的时候使用0,1,2的index来获取
    v3 = models.Business.objects.all().values_list('id', 'caption')
    
    • 举例:
    # urls.py
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^business/$', views.business),
        url(r'^host/$', views.Host.as_view()),
    ]
    
    # views.py
    def business(request):
        v1 = models.Business.objects.all()  
        v2 = models.Business.objects.all().values('id', 'caption')  
        v3 = models.Business.objects.all().values_list('id', 'caption')  
        return render(request, 'business.html', {'v1': v1, 'v2': v2, 'v3': v3})
    
    
    # business.html
    <h1>(对象获取)</h1>
    {% for foo in v1 %}
        <li>{{ foo.id }}--{{ foo.caption }}--{{ foo.code }}</li>
    {% endfor %}
    <h1>(字典获取)</h1>
    {% for foo in v2 %}
        <li>{{ foo.id }}--{{ foo.caption }}</li>
    {% endfor %}
    <h1>(元祖获取)</h1>
    {% for foo in v3 %}
        <li>{{ foo.0 }}--{{ foo.1 }}</li>
    {% endfor %}
    

    2.连表三种获取方式

    # QuerySet内部为对象,模板获取的时候用"."来获取
    v1 = models.Host.objects.filter(nid__gt=0)
    
    # QuerySet内部为key、value的字典,因为是字典,在模板中获取的时候用"."来获取,
    v2 = models.Host.objects.all().values('nid', 'hostname', 'b_id', 'b__caption', 'b__code')
    
    # QuerySet内部为元组,因为是元组,在模板中获取的时候使用0,1,2的index来获取
    v2 = models.Host.objects.all().values_list('nid', 'hostname', 'b_id', 'b__caption', 'b__code')
    
    
    • 举例
    # urls.py
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^business/$', views.business),
        url(r'^host/$', views.Host.as_view()),
    ]
    
    # views.py
    class Host(View):
        def get(self, request):
            v1 = models.Host.objects.filter(nid__gt=0)
            v2 = models.Host.objects.all().values('nid', 'hostname', 'b_id', 'b__caption', 'b__code')
            v3 = models.Host.objects.all().values_list('nid', 'hostname', 'b_id', 'b__caption', 'b__code')
            return render(request, 'host.html', {'v1': v1, 'v2': v2, 'v3': v3})
    
        def post(self, request):
            pass
    
    
    # host.html
    <h1>对象</h1>
    {% for row in v1 %}
                <tr host_id="{{ row.nid }}" b_id="{{ row.b_id }}">
                <td>{{ row.hostname }}</td>
                <td>{{ row.ip }}</td>
                <td>{{ row.port }}</td>
                <td>{{ row.b.caption }}</td>
                </tr>
    {% endfor %}
    
    <h1>字典</h1>
    {% for row in v2 %}
                <tr host_id="{{ row.nid }}" b_id="{{ row.b_id }}">
                <td>{{ row.hostname }}</td>
                <td>{{ row.b__caption }}</td>
                </tr>
    {% endfor %}
    
    <h1>元组</h1>
    {% for row in v3 %}
                <tr host_id="{{ row.0 }}" b_id="{{ row.2 }}">
                <td>{{ row.1 }}</td>
                <td>{{ row.3 }}</td>
                </tr>
    {% endfor %}
    
    
  • 相关阅读:
    算法导论:快速排序
    lintcode:打劫房屋 III
    lintcode:打劫房屋II
    lintcode:打劫房屋
    算法导论:二叉搜索树
    算法导论:整齐打印
    砝码称重问题二
    多重背包问题II
    多重背包问题
    lintcode:背包问题II
  • 原文地址:https://www.cnblogs.com/forsaken627/p/7691807.html
Copyright © 2020-2023  润新知