Django基础(一)

安装django

pip3 install django

安装成功后在python的目录下的Scripts目录下生成了django-admin.exe

在windows命令行窗口执行django-admin.exe startproject mysite就会生成mysite文件夹

cd mysite

python manage.py runserver 程序可以工作了

创建Django工程

执行django-admin startproject mysite  【工程名称】

mysite
    - mysite         # 对整个的程序进行配置
        - init   
        - settings   # 配置文件
        - url        # URL对应关系
        - wsgi       # 遵循WSGI规范, uwsgi + nginx
    - manage.py      # 管理Django程序
- python manage.py
- python manage.py startapp xx
- python manage.py makemigrations #
- python manage.py migrate #

运行Django功能

python manage.py runserver 127.0.0.1:8001

#urls.py

from django.conf.urls import url
from django.contrib import admin
from django.shortcuts import HttpResponse

import time
def home(request):
    return HttpResponse('<h1>Hello</h1>')

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^h.html/', home),    
]

chouti

    - chouti

        - 配置

    - 主站 app

    - 后台管理 app

创建app

python manage.py startapp cmdb

python manage.py startapp openstack

python manage.py startapp xxxxxx

app:
    migrations   #数据修改表结构
    admin   #Django提供的后台管理
    apps    #配置当前app
    models   #ORM,写指定的类,通过命令可以创建数据库结构
    tests   #单元测试
    views   #业务代码

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',
            ],
        },
    },
]
View Code

2.配置静态目录

static

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)

<link rel="stylesheet" href="/static/commons.css" />

写个登陆页面

#views.py
from django.shortcuts import HttpResponse
from django.shortcuts import render
from django.shortcuts import redirect
def login(request):
# 包含用户提交的所有信息

# 获取用户提交的方法
#print(request.method)
error_msg = ''
if request.method == "POST":
# 获取用户通过POST提交过来的数据
user=request.POST.get('user', None)
pwd=request.POST.get('pwd', None)
if user =='root' and pwd == '123':
return redirect('http://www.baidu.com')
else:
error_msg="用户名或密码错误"
return render(request,'login.html', {'error_msg': error_msg})
#urls.py
from django.conf.urls import url
from django.contrib import admin
from cmdb import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login', views.login),
]

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/login/" method="POST" enctype="multipart/form-data">
        <p>
            <input type="text" name="user" placeholder="用户名" />
        </p>
        <p>
            <input type="password" name="pwd" placeholder="密码" />
        </p>
        <p>
            男:<input type="radio" name="gender" value="1"/>
            女:<input type="radio" name="gender" value="2"/>
        </p>
        <p>
            足球:<input type="checkbox" name="favor" value="11"/>
            篮球:<input type="checkbox" name="favor" value="22"/>
            乒乓球:<input type="checkbox" name="favor" value="33"/>
        </p>
        <p>
            <select name="city" multiple>
                <option value="sh">上海</option>
                <option value="bj">北京</option>
                <option value="tj">天津</option>
            </select>
        </p>
        <p>
            <input type="file" name="fafafa">
        </p>
        <input type="submit" value="提交"/>
    </form>
</body>
</html>
View Code

定义视图函数

app下的views.py

def func(request):
    # request.method    GET/POST
    
    # http://127.0.0.1:8009/home?nid=123&name=alex
    # request.GET.get('',name) # 获取请求发来的数据
    
    # request.POST.get('',None)
    
    # return HttpResponse('字符串')
    # return render(request, "HTML模板的路径")
    # return redirect('/只能填URL')

for循环

def func(request):
    return render(request, "index.html", {'current_user':'tom','user_list': ['tom','eric']})

index.html

<html>
..
    <body>
        <div>{{current_user}}</div>
        <ul>
            {% for row in user_list %}
                {% if row == "tom" %}
                    <li>{{ row }}</li>
                {% endfor %}
            {% endfor %}
        </ul>
    </body>

</html>
View Code

条件

def func(request):
    return render(request, "index.html", {
            'current_user':'tom',
            "age": 18,
            'user_list': {'tom','jerry'},
            'user_dict': {'k1':'v1','k2':'v2'}})

index.html

<html>
..
    <body>
        <div>{{current_user}}</div>
        
        <a>{{user_list.1}}</a>
        <a>{{user_dict.k1}}</a>
        <a>{{user_dict.k2}}</a>
        
        {% if age %}
            <a>有年龄</a>
            {% if age > 16 %}
                <a>老男人</a>
            {% else %}
                <a>小鲜肉</a>
            {% endif %}
        {% else %}
            <a>无年龄</a>
        {% endif %}
        
    </body>
</html>

Django请求生命周期

->URL对应关系->视图函数->返回用户字符串
->URL对应关系->视图函数->打开一个HTML文件,读取内容

创建django项目的基本准备

django-admin startproject mysite

mysite
    mysite
        - 配置文件
        - url.py
        - settings.py

cd mysite
python manage.py startapp cmdb

mysite
    mysite
        - 配置文件
        - url.py
        - settings.py
    cmdb
        - views.py
        - admin.py
        - models.py  # 创建数据库表

3.配置

模板路径
静态文件路径

4.编写程序

    a.  urls.py
      
        /index/  -> func
    b.  views.py
         
        def func(request):
            # 包含所有的请求数据
            ...
            return HttpResponse('字符串')
            return render(request, 'index.html', {'':''})
            return redirect('URL')

    c. 模板语言
        return render(request, 'index.html', {'li': [11,22,33]})
        {% for item in li %}
            <h1>{{item}}</h1>
        {% endfor %}
                
        ****索引******
        <h2>{{item.0}}</h2>

路由系统

1.url(r'^index/', views.index),
  url(r'^home/', views.Home.as_view()),
2.url(r'^detail-(d+).html', views.detail),
3.url(r'^detail-(?P<nid>d+)-(?P<uid>d+).html', views.detail),   推荐
4.name
对URL路由关系进行命名,以后可以根据此名称生成自己想要的URL
url(r'^dsfdsfd/', 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')

def func(request, *args, **kwasrgs):
from django.urls import reverse
url1 = reverse('i1') # dsfdsfd
url2 = reverse('i2', args=(1,2,)) # yue/1/2/
url3 = reverse('i3', kwargs={'pid': 1, 'nid': 9}) # buy/1/9/

xxx.html
{% url 'i1' %} # dsfdsfd
(% url 'i2' 1 2 %) # yug/1/2/
{% url 'i3' pid=1 nid=9 %} # buy/1/9/
5.多级路由

#project/urls.py
from django.conf.urls import url,include
from django.contrib import admin

urlpatterns = [
    url(r'^cmdb/', include("app01.urls")),
    url(r'^monitor/', include("app02.urls")),
]

#app01/urls.py
from django.conf.urls import url,include
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^login/', views.login),
]

#app02/urls.py
from django.conf.urls import url,include
from django.contrib import admin
from app02 import views

urlpatterns = [
    url(r'^login/', views.login),
]

6.默认值

7.命名空间

# http://www.cnblogs.com/wupeiqi/articles/5237704.html

  实战:
      a.
          url(r'^detail-(d+)-(d+).html', views.detail),
          
          def func(request, nid, uid):
              pass
          
          def func(request, *args):
              args = (2,9)
              
          def func(request, *args, **kwargs):
              args = (2,9)

      b. url(r'^detail-(?P<nid>d+)-(?P<uid>d+).html', views.detail)
          def func(request, nid, uid):
              pass

          def func(request, *kwargs):
              kwargs = {'nid': 1, 'uid': 3}

          def func(request, *args, **kwargs):
              kwargs = {'nid': 1, 'uid': 3}

视图

#获取请求的三种方式
request.GET
request.POST
request.FILES
#checkbox等多选的内容
request.POST.getlist()

#上传文件,for标签  enctype="multipart/form-data"
obj = request.FILES.get('fafafa')
import os
filepath = os.path.join('upload', obj.name)
f = open(filepath, 'wb')
for i in obj.chunks():
    f.write(i)
f.close()

FBV & CBV

/index/ -> 函数名
/index/ -> 类

#home.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <form action="/home/" method="POST">
        <input type="text"/>
        <input type="submit"/>
    </form>
</body>
</html>

#urls.py
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^index/', views.index),
    url(r'^login/', views.login),
    url(r'^home/', views.Home.as_view()),
]
View Code
#views.py
from django.views import View
class Home(View):

    def dispatch(self, request, *args, **kwargs):
        # 调用父类中的dispatch
        print('before')
        result = super(Home, self).dispatch(request, *args, **kwargs)
        print('after')
        return result

    def get(self,request):
        print(request.method)
        return render(request, 'home.html')

    def post(self,request):
        print(request.method)
        return render(request, 'home.html')

模板

ORM操作

select * from tb where id > 1
# 对应关系
models.tb.objects.filter(id__gt=1)
models.tb.objects.filter(id=1)
models.tb.objects.filter(id__lt=1)

创建类

1.根据类自动创建数据库表

#app01/models.py

from django.db import models

class Userinfo(models.Model):
    #id列自增,主键
    #用户名列,字符串类型,指定长度
    username = models.CharField(max_length=32)
        username = models.CharField(max_length=64)

>python manage.py makemigrations
>python manage.py migrate

注:
Django默认使用MySQLdb模块 (python3无法使用) 链接MySQL
修改为pymysql,在project同名文件夹下的__init__文件中添加如下代码即可:

#project_name/__init__.py
import pymysql
pymysql.install_as_MySQLdb()

2.根据类对数据库表中的数据进行各种操作

#views.py
from app01 import models

def orm(request):
    #创建
    models.UserInfo.objects.create(
        username='root',     # 数据库中会增加这两条数据
        password='123'
   ) 
    或
    dic = {'username': 'tom','password': '666'}
    models.UserInfo.objects.create(**dic)
    或
    obj = models.UserInfo(username='root',password='123')
    obj.save()
    return HttpResponse('orm')

#查
#result = models.UserInfo.objects.all() #拿到表中的所有数据,是QuerySet类型

result = models.UserInfo.objects.filter(username='root') # 相当于where查询
    for row in result:
print(row.id, row.username, row.password)
    print(result)

#删除
models.UserInfo.objects.filter(id=4).delete()
#更新
models.UserInfo.objects.all().update(password=666)
models.UserInfo.objects.filter(id=3).update(password=69)
return HttpRersponse('orm')
#views.py
def login(request):
    if request.method == "GET":
        return render(request, 'login.html')
    elif request.method == "POST":
        u = request.POST.get('user')
        p = request.POST.get('pwd')
        #obj = models.UserInfo.objects.filter(username=u,password=p).first()
        #print(obj)         
        #count=models.UserInfo.objects.filter(username=u,password=p).count()
obj = models.UserInfo.objects.filter(username=u,password=p).first()
if obj:
return redirect('/index/')
else:
return render(request,'login.html')
else:
return redirect('/index/')
def user_info(request):
if request.method == "GET":
user_list = models.UserInfo.objects.all()
return render(request, 'user_info.html', {'user_list': user_list})
elif request.method == "POST":
u = request.POST.get('user')
p = request.POST.get('pwd')
models.UserInfo.objects.create()
return redirect('/cmdb/user_info/')

字段:

    字符串类型

    数字

    时间

    二进制

    自增

字段参数:

    null              -->db是否可以为空
    default           -->默认值
    primary_key       -->主键
    db_column         -->列名        db_column='cp'
    db_index          -->是否是普通索引  db_index=True
    unique            -->是否是唯一索引  unique=True
    unique_for_date   -->只对时间做索引
    unique_for_month  -->只对月份做索引
    unique_for_year   -->只对年份做索引
    choices           -->django admin中显示下拉框,避免连表查询
    
    class UserInfo(models.Model):
    ...
        user_type_choice = (      
            (1, '超级用户'),     # 把选项放到了内存中,而没有放入一个表里面
            (2, '普通用户'),
            (3, ''),
        )
        user_type_id = models.IntergerField(choices=user_type_choice,default=1)  #默认为超级用户
    
        
    auto_now_add      -->创建时自动生成时间  ctime = models.DateTimeField(auto_now_add=True, null=True)
    auto_now          -->更新时自动更新为当前时间  uptime = models.DateTimeField(auto_now=True, null=True)
    #obj = UserGroup.objects.filter(id=1).update(caption='CEO')  --->不会更新时间,Django不支持
    #obj = UserGroup.objects.filter(id=1).first()                --->会更新时间
    #obj.caption = 'CEO'
    #obj.save()
    blank             -->在django admin中是否可以为空  username = models.CharField(max_length=32,blank=True)
    verbose_name      -->django admin显示字段中文 username = models.CharField(max_length=32,blank=True,verbose_name='用户名')
    editable          -->django admin中是否可以被编辑  username = models.CharField(max_length=32,blank=True,verbose_name='用户名',editable=False)
    error_message     -->错误信息  password = models.CharField(max_length=60,error_message={'required':'请输入密码'})
    help_text         -->django admin中显示提示 password = models.CharField(max_length=60,help_text='pwd')
    validators        -->django form,自定义错误信息

外键操作

class UserGroup(models.Model):
    uid = models.AutoField(primary_key=True)
    caption = models.CharField(max_length=32, unique=True)
    ctime = models.DateTimeField(auto_now_add=True, null=True)
    uptime = models.DateTimeField(auto_now=True,null=True)
    
class UserInfo(models.Model):
    #id列自增,主键
    #用户名列,字符串类型,指定长度
    #字符串,数字,时间,二进制
    username = models.CharField(max_length=32,blank=True,verbose_name='用户名')
    password = models.CharField(max_length=60, help_text='pwd')
    email = models.CharField(max_length=60)
    test = models.EmailField(max_length=19,null=True,error_message={'invalid':'请输入密码'})    
        
    user_type_choice = (      
            (1, '超级用户'),     # 把选项放到了内存中,而没有放入一个表里面
            (2, '普通用户'),
            (3, ''),
        )
    user_type_id = models.IntergerField(choices=user_type_choice,default=1)
    # user_group_id 数字
    user_group = models.ForeignKey("UserGroup",to_field='uid',default=1)  # 代指的是对象    
        
注:        
user_list = models.UserInfo.objects.all()
for row in user_list:
    print(row.user_group_id)   #代表数据库中真实存在的数据
    print(row.user_group)      #指的是对象,是UserGroup类的对象,对象中封装了很多值,取得话通过.uid等取值
    print(row.user_group.uid)   ==  row.user_group_id  
    print(row.user_group.caption)
    print(row.user_group.uptime)

更新

#一对多
#user_list = models.UserInfo.objects.all()

models.UserInfo.objects.create(
    username='root1',
    password='123',
    email='dsf',
    test=''dfd,
    user_group_id=1    # 比下面的方式好的原因在于,只进行一次数据库操作
)


models.UserInfo.objects.create(
    username='root1',
    password='123',
    email='dsf',
    test=''dfd,
    user_group_id=models.UserInfo.objects.filter(id=1).first()  #  先查询,再创建,进行了两次数据库操作
)

根据类对数据库表中的数据进行各种操作

一对多
a.外键
b.对于这个外键默认生成数据库的时候应该是
外键字段_id
c.根据 外键字段_id 进行创建数据,这样就省了一次数据查询
models.tb.object.create(name='root',user_group_id=1)

请求的生命周期

    路由系统--->视图函数(获取模板+数据--->渲染)--->字符串返回给用户

    1.路由系统

        /index/                          --------> 函数或类.as_view()

        /detail/(d+)                   -------->函数(参数) 或 类.as_view()   (参数)

        /detail/(?P<nid>d+)     -------->函数(参数)或  类.as_view()    (参数)

        /detail/                          -------->include("app01.urls")

        /detail/      name='a1'   -------->include("app01.urls")

                                                   ---视图中:reverse

                                                   ---模板中:{% url "al" %}

    2.视图函数

        FBV:函数

            def index(request, *args, **kwasrgs):

                  .....

        CBV:类

            class Home(views.View):

                def get(self,request,*args,**kwasrgs):

                    ......

      #获取用户请求的数据

      request.POST.get

      request.GET.get

      request.FILES.get

      ........getlist()      适用于多选情况,如checkbox

      request.path_info      获取当前请求的URL

      文件对象 = request.FILES.get()

      文件对象.name

      文件对象.size

      文件对象.chunks()  分块儿取数据

      #给用户返回数据

      render(request,'模板文件的路径',{'k1': [1,2,3,4],'k2':{'name':'zhang','age':22}})

      redirect('URL')

      HttpResponse(字符串)

    4.模板语言

render(request, "模板路径",{'模板语言':1234,'k1': {1,2,3,4}, "k2": {'name': 'zhang', 'age': 22}})  
      <html>
      <body>
          <h1>{{ obj }}</h1>
          <h1>{{ k1.3 }}</h1>
          <h1>{{ k2.name }}</h1>
          {% for i in k1 %}
               <p> {{ i }} </p>
          {% endfor %}

           {% for row in k2.keys %}
                 {{ row }}
           {% endfor %}

           {% for row in k2.keys %}
                 {{ row }}
           {% endfor %}

           {% for row in k2.values %}
                 {{ row }}
           {% endfor %}

           {% for k,v in k2.items %}
                 {{ k }} - {{ v }}
           {% endfor %}
      </body>
      </html>

    5.ORM

   a.创建类和字段

           class User(models.Model):
               id = models.IntergerField()
               name = models.CharField(max_length=10)   #字符长度

           python manage.py makemigrations
           python manage.py migrate

           #settings注册APP

      b.操作

          增 

              models.User.objects.create(name='tom',age=18)

              dic = {'name' : 'tom', 'age' : 20}

              models.User.objects.create(**dic)

 

              obj = models.User(name='tom',age=20)

              obj.save()

          删 

               models.User.objects.filter(id=1).delete()

          改 

               models.User.objects.filter(di__gt=1 ).update(name=''tom,age=22)

               dic = {'name' : 'tom', 'age' : 20}

               models.User.objects.filter(id__gt=1).update(**dic)

          查 

               models.User.objects.filter(id=1,name='root')

               models.User.objects.filter(id__gt=1,name='root')

               models.User.objects.filter(id__lt=1)

               models.User.objects.filter(id__gte=1)

               models.User.objects.filter(id__lte=1)

               dic = {'name':'xx','age':'22'}

               models.User.objects.filter(**dic)

 

               v1 = models.Business.objects.all()

               # QuerySet,内部元素都是对象

               v2 = models.Business.objects.all().values('id','caption')

               # QuerySet,内部元素都是字典

               v3 = models.Business.objects.all().value_list('id','caption')

               # QuerySet,内部元素都是元组

 

              # 获取到的一个对象,如果不存在就报错

              models.Business.objects.get(id=1)

              models.Business.objects.filter(id=1).first()   # 获取到的是对象 或 None

 

              外键:

                 v = models.Host.objects.filter(nid__gt=0)

                 v[0].b.caption  ------>   通过 . 进行跨表

 

         外键:
               class UserType(models.Model):
                   caption = models.CharField(max_length=32)
               # 1. 普通用户
               # 2. VIP用户
               # 3. 游客               

               class User(models.Model):
                   age=models.IntergerField()
                   name=models.CharField(max_length=10)    # 字符长度
                   # user_type_id=models.intergerField()       # 

                   user_type = models.ForeignKey("UserType",to_field='id')   # 约束

              #   name    age    user_type_id

              #   tom       20            2

              #   jerry      20           3

              #   peter     20            1

    6  

 Ajax 

$.ajax({

    url: '/host',         # 要提交到哪里

    type: "POST",    #以什么方式提交

    data: {'k1':123, 'k2':"root"}   # 要提交的数据

    success: function(data){     # 发请求过去后,函数不会执行,等到服务端返回数据这个函数就会自动被触发

        //  data是服务器端返回的字符串

        var obj = JSON.parse(data) ;          //转化为json对象  ,执行JSON.parse()的前提是  形似列表或字典的数据结构

    }

建议:永远让服务器端返回一个json处理过的字典

return HttpResponse(json.dumps(字典))

在这里不能使用redirect(),render()

})

 

原文地址:https://www.cnblogs.com/Ryans-World/p/7233393.html