初识Djiango

老师的博客:点我

内容主要是看老师的博客

下面是自己的写的某些自己当时不太懂的。

关于Django的版本的问题

Django官网下载页面

在官网上显示lts的是表示支持长期版本。所以最好下载1.11版本的,这是官网支持长期更新的,当然1.8的版本也可以。

在cmd上下载

pip3 install django==1.11.11 -i https://pypi.douban.com/simple

下载完成后再cmd上输入

django-admin

会显示一些字符串,如果报错说明没有添加环境变量。

把Django的文件路径添加到环境变量来里面。环境变量在计算机-单击-属性-高级属性里面。

Django的环境变量在pip同一个文件夹里面。自己看看去吧。

在cdm上创建Django文件。见下图

当然在pycharm上创建也可:在file上打开New Project,添加文件。见下图

 一定要在勾选存在的解释器,然后在新的窗口上打开。

关于Django的运行

安装好Django之后,就开运行了,结构如下

├── manage.py  # 管理文件
└── mysite  # 项目目录
    ├── __init__.py
    ├── settings.py  # 配置
    ├── urls.py  # 路由 </span>--&gt;<span style="color: #000000;"> URL和函数的对应关系
    └── wsgi.py  # runserver命令就使用wsgiref模块做简单的web 

然后开始运行文件了。先说说一下setting的文件,里面都是一些设置的文件。

setting

在setting里面有个项目路径,后面所有的拼接路径都会用得到,大约在13行左右setting

import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
# 表示当文件的上两级文件
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# os.path.abspath(__file__)表示当前的绝对路径
# os.path.dirname(os.path.abspath(__file__))表示当前的绝对路径的上一级

下面是HTML的文件文件路径  在函数返回时render(request,"HTML")所需要的路径。大约在53行左右。

ROOT_URLCONF = 'mysite.urls'

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

 关于HTML文件的引入的文件的导入路径,在最后后面。

# 静态文件的别名
STATIC_URL = '/static/'

# 所有静态文件(CSS,JS AND SO ON)都放在下面的路径
# 可以存放多个
STATICFILES_DIRS=[
    os.path.join(BASE_DIR,"static"),
]

注意在HTML文件中必须加上别名,以便告诉Django去哪里了找文件。

注意以上所有的拼接路径都可以不止添加一个。

关于post的注释文件

    # 'django.middleware.csrf.CsrfViewMiddleware',

大约在47行左右

打开HTML文件的两种形式;

1,用cmd打开。

django-admin startproject 文件名(及最开始创建的那个文件)

2.用pycharm打开

右上角的绿色的那个开始键

无论是哪种方式打开,都会给你一个默认地址,你可以从浏览器打开。

app

 app的创建

    python manage.py startapp app的名字
            或者直接在创建项目时,创建app

 

在setting中添加app的路径(如果是pycharm添加qpp的自动添加路径)

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 'app01',
    'app01.apps.App01Config' #推荐写这个
]

 此时可以将所有的函数放在app的views中的,此时记得改变项目的ulrs中的导入问题就好。

例如

from app01 import views

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

]

 ORM

 Django来操作数据库

由于Django中的ORM不支持创建数据可,所以自己首先在mysql中创建数据库

创建表

首先在setting中修改数据库的默认设置(用mysql数据库) 

DATABASES = {
    'default':{
        'ENGINE': 'django.db.backends.mysql',  # 连接的数据库类型
        'HOST': '127.0.0.1',  # 连接数据库的地址
        'PORT': 3306,  #  端口
        'NAME': "day61",  # 数据库名称
        'USER': 'root',  # 用户
        'PASSWORD': ''  # 密码
    }
}

 由于Django的默认使用MySQLdb来连接数据库的,不支持python3.所以需要换位pymysql来代替MySQLdb来连接数据库。

在项目里面的的init里面输入以下代码即可:

import pymysql
# 告诉Django用pymysql来代替默认的MySQLdb
pymysql.install_as_MySQLdb()

 然后在app的目录下的models下创建类

from django.db import models

# Create your models here.
# ORM语句只能写在这里,写在其他的方Django则找不到
class userinfo(models.Model):
    id=models.AutoField(primary_key=True) #  创建一个自增的id
    user=models.CharField(null=False, max_length=20) #创建一个varchar(20)且不能为空
password=models.IntegerField()

 然后就是在项目中的terminal中输入下面的两条参数即可

python3 manage.py makemigrations
python3 manage.py migrate

 完成,查看day61的表发现会有一大堆的表,我们只需要关注我们自己创建的表

app01_userinfo

 查看表的结构

mysql> desc app01_userinfo;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(11)     | NO   | PRI | NULL    | auto_increment |
| user     | varchar(20) | NO   |     | NULL    |                |
| password | int(11)     | NO   |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.07 sec)

创建完成 

删除表和改动表

直接注释类就删除表了。

直接改动类就是修改表了

然后执行既可以了

python3 manage.py makemigrations 用小本本把models.py文件中的改动记录在app01 下面的templa里面
python3 manage.py migrate  翻译sql语句,并且执行

表的操作 

下面的表的操作由于是几个不同的表,所以最后有个总结的表,可以直接看总结的表

电脑的文件的Djan文件day62

查看表

用HTML查看表

首先在useinfo里面随便添加几条数据,然后在ulrs里面添加相应的函数 

在urls中写入相应的对应关系

url(r'^info/',views. info),

在app01中的vies写入相应的函数

def info(requset):
    ret=models.userinfo.objects.all()
    return render(requset,"info.html",{"userinfo_list":ret})

注意:此时的ret表示从models中的useinfo表取出所有的数据

然后在HTML页面拿出所有的所有得数据,html支持for循环

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>info</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <script src="/static/jQuery.js"></script>
    <link href="/static/normalize.css" rel="stylesheet">
    <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.min.css" rel="stylesheet">
    <link href="/static/toastr/toastr.min.css" rel="stylesheet">
</head>
<body>
<table class="table success" border="1px">
    <thead>
    <tr>
        <th class="success">id</th>
        <th>name</th>
        <th>password</th></tr>
    </thead>
    <tbody>
    {% for userinfo in userinfo_list %}
    <tr>
        <td class="warning">{{ userinfo.id }}</td>
        <td class="danger">{{ userinfo.user }}</td>
        <td class="progress">{{ userinfo.password }}</td>
    </tr>
    </tbody>{% endfor %}
</table>
<a href="/add_list/">添加用户:</a>{#在urls中找到对应的关系#}
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/jQuery.js"></script>
<script src="/static/toastr/toastr.min.js"></script>
</body>
</html>

然后你就可以在html中查看所有数据库的数据了

增加数据

首先在info页面添加添加的数据的连接,见上面

在urls添加对应关系

url(r'^add_list/',views. add_list),

添加函数

def add_list(request):
    if request.method == "POST":
        print("+++++++++++++++++++++",request.POST)
        add_name=request.POST.get("name",None)
        add_pad=request.POST.get('password',None)
        models.userinfo.objects.create(user=add_name,password=add_pad)
        print("添加成功")
        return render(request,"info.html")
    else:
        return render(request,"add_list.html")

然后HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>add_list</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <script src="/static/jQuery.js"></script>
    <link href="/static/normalize.css" rel="stylesheet">
    <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.min.css" rel="stylesheet">
    <link href="/static/toastr/toastr.min.css" rel="stylesheet">
</head>
<body>
<form class="form-group" action="" method="post">
<p>用户名:<input type="text" name="name"></p>
    <p>密码:<input type="text" name="password"></p>
<input type="submit" value="提交信息" >
</form>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/jQuery.js"></script>
<script src="/static/toastr/toastr.min.js"></script>
</body>
</html>

ok了。在添加数据中的时候要注意在创建表的时候的数据类型,不然后在Django中报错

在添加的数据的html中,在form中一定不要把action给写入,不然在提交时就可能不会执行函数,而直接跳转了,跳转的页面应该在views中的函数中写入。不然就会报错

注意,在所有的页面中的跳转(action 和 href 都可以写    /本地对应关系/),在Django中跳转本地都是类似于 info.html

 补充:

关于在__srt__的使用方法:

class Person1():
    def __init__(self,name,age):
        self.name=name
        self.age=age
    def __str__(self):
        return "<{}---{}>".format(self.name,self.age)
class Person2():
    def __init__(self, name, age):
        self.name = name
        self.age = age
xm=Person1("xM",20)
xz=Person2("xz",21)
print(xm)
print(xz)

输出结果

<xM---20>
<__main__.Person2 object at 0x00000000010A8B38>

 删除

在HTML中的删除

首先在urls中写入地址(对应关系)

url(r'^delect_list/', views.delect_list),

 在views中的写入函数

def delect_list(request):
    print(request.GET)
    del_id=request.GET.get("id",None)
    print(del_id)
    del_thing=models.publisherL.objects.get(id=del_id)
    print(del_thing)
    if del_thing:
        del_thing.delete()
        return redirect("/info/")
    else:
        return HttpResponse("删除失败")

解释函数的参数

提百度为例子
https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&tn=baidu&wd=html按钮跳转
https://www.baidu.com/表示地址
?ie=utf-8&f=8&rsv_bp=1&tn=baidu&wd=html按钮跳转  表示请求的条件 &&表示并列条件
request.GET表示获取条件,以字典的形式表示

然后html的页面

 html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>info</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <script src="/static/jQuery.js"></script>
    <link href="/static/normalize.css" rel="stylesheet">
    <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.min.css" rel="stylesheet">
    <link href="/static/toastr/toastr.min.css" rel="stylesheet">
</head>
<body>
<table class="table table-bordered table-hover">
    <thead>
    <tr class="warning">
        <th>序号</th>
        <th>id</th>
        <th>出版社</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
    {% for every_info in info_list %}
        <tr class="success">
            <td>{{ forloop.counter }}</td>
            <td>{{ every_info.id }}</td>
            <td>{{ every_info.name }}</td>
            <td><button class="button" ><a href="/delect_list/?id={{ every_info.id }}">删除</a></button></td>
        </tr>
    {% endfor %}
    </tbody>
</table>
<button class="button" id="add_list">增加数据</button>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/jQuery.js"></script>
<script src="/static/toastr/toastr.min.js"></script>
<script>
    $("#add_list").on("click",function () {
     window.location.href="/add_list/";
    })

 主要是删除的那段结合函数看

 改动表、

函数:

def edit_list(request):
    try:
        if request.method == "POST":
            print(request.POST)
            id_still=request.POST.get("id")
            new_name=request.POST.get("name")
            edit_element=models.publisherL.objects.get(id=id_still)
            print("===================================",edit_element)
            edit_element.name=new_name
            edit_element.save()
            return redirect("/info/")
        else:
            name = request.GET.get("name")
            id = request.GET.get("id")
            return render(request,"edit_list.html",{"edit_name": name,"edit_id": id})
    except:
        return HttpResponse("不要乱输入")

 html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>edit_list</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <script src="/static/jQuery.js"></script>
    <link href="/static/normalize.css" rel="stylesheet">
    <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.min.css" rel="stylesheet">
    <link href="/static/toastr/toastr.min.css" rel="stylesheet">
</head>
<body>
<form class="form-group"  method="post">
    <input type="text" value={{ edit_id }} class="hidden" name="id" >
    <div class="form-group">
        <label for="edit_name">出版社的名字:</label>
        <input name="name" type="text" placeholder={{ edit_name }}>
    </div>
    <div class="form-group">
        <input type="submit" class="btn btn-danger" value="确认"></input>
        <button class="btn btn-success"><a href="/info/">取消</a></button>
    </div>
</form>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/jQuery.js"></script>
<script src="/static/toastr/toastr.min.js"></script>
</body>
</html>

全部文件 在电脑的day62,有时间在上传上来。

 关于外键的的表以及HTML的使用:

下面是一个项目 day63

 创建时:

from django.db import models

# Create your models here.
class book(models.Model):
    id=models.AutoField(primary_key=True)
    title=models.CharField(max_length=20,unique=True,null=False)
    publisher=models.ForeignKey(to="publisher") #  “”如果表示现在不存在,后面创建里面找 默认匹配id
class publisher(models.Model):
    id=models.AutoField(primary_key=True)
    publisher=models.CharField(max_length=30,null=False)

注意:外键的创建时一般不需要publisher_id,因为在Django中会自动的添加这个后缀。

函数

from django.shortcuts import render,HttpResponse,redirect
from app01 import models
# Create your views here.



def book_list(request):
    all_book=models.book.objects.all()
    return render(request,"book_list.html",{"book_list": all_book})
def add_list(request):
    if request.method=="POST":
        title=request.POST.get('title').strip()
        if title:
            publisher_id=request.POST.get("publisher")
            models.book.objects.create(title=title,publisher_id=publisher_id)
            return redirect("/book_list/")

    all_publisher=models.publisher.objects.all()
    all_book = models.book.objects.all()
    return render(request,"add_list.html",{"all_book":all_book, "all_pulisher": all_publisher})

注意关于外键的添加两种方法:

publisher_id=request.POST.get("publisher")
# 外键的两种写法 第一种(推荐)
 # 直接写入
models.book.objects.create(title=title,publisher_id=publisher_id)
# 第二种
# 先找到对应的外键
find_foreignkey=models.publisher.objects.get(id=publisher_id)
# 关联外键
models.book.objects.create(title=title,publisher=find_foreignkey)

在HTML中的调用的时候

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>add_list</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <script src="/static/jQuery.js"></script>
    <link href="/static/normalize.css" rel="stylesheet">
    <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.min.css" rel="stylesheet">
    <link href="/static/toastr/toastr.min.css" rel="stylesheet">
</head>
<body>
<h1 class="h1 text-center text-warning">添加信息</h1>
<form class="form" action="/add_list/" method="post">
<p>
    <label for="name" >书目名:<input type="text" id="name" name="title"></label>
</p>
<p>
    <label for="publisher">出版社:</label>
    <select class="" name="publisher">
    {% for i in all_book %}
        <option value={{ i.publisher.id}}>{{ i.publisher.publisher }}</option>

    {% endfor %}
    </select>
</p>
<p>
    <input type="submit" class="btn" value="保存">
</p>
</form>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/jQuery.js"></script>
<script src="/static/toastr/toastr.min.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>bool_list</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <script src="/static/jQuery.js"></script>
    <link href="/static/normalize.css" rel="stylesheet">
    <link href="/static/bootstrap/css/bootstrap.min.css" rel="stylesheet">
    <link href="/static/font-awesome/css/font-awesome.min.css" rel="stylesheet">
    <link href="/static/toastr/toastr.min.css" rel="stylesheet">
</head>
<body>
<h1 class="h1 text-center text-warning">所有书籍的信息</h1>
<table class="table table-bordered table-hover">
    <thead>
    <tr class="danger">
        <th>序号</th>
        <th>id</th>
        <th>title</th>
        <th>publisher</th>
        <th>测试</th>
        <th>测试</th>
    </tr>
    </thead>
    <tbody >
    {% for i in book_list %}
    <tr class="success">
        <td>{{forloop.counter}}</td>
        <td>{{i.id}}</td>
        <td>{{i.title}}</td>
        <td>{{i.publisher.publisher}}<======>i.publisher.publisher</td>
        <td>{{i.publisher.id}}<======>i.publisher.id</td>
        <td>{{i.publisher_id}}<======>i.publisher_id</td>
    </tr>
    {% endfor %}
    </tbody>

</table>
<p><a href="/add_list/">添加一条数目</a></p>








<script src="/static/bootstrap/js/bootstrap.min.js"></script>
<script src="/static/jQuery.js"></script>
<script src="/static/toastr/toastr.min.js"></script>
</body>
</html>

注意:在HTML的调用时,我们要分清各种调出来的东西 

i.publisher.publisher <------------>publisher的publisher项
i.publisher.id <----------------->publisher的id项
i.publisher_id <------------------>外键对应的项,此时相当于publisher的id项
i.publisher <----------------------->pulisher这个对象

修改列表的时候,添加一个列的名字且不为空时:

在app中models的book添加

 address=models.CharField(max_length=20,null=False)

然后在开始执行,pycharm的另外一种写法

此时 python manage.py makemigrations 可以简写为makemigrations

但是我的的pycharm好像有点问题

好吧老方法;

尴尬上面写反了

第一种方法:

选着1

OK了

选着2

改写

publisher=models.CharField(max_length=30,null=False,default="中国")

重新输入就好

 多对多的时候

    9.多对多
            post请求传输的一个name对应多个值是,需要用getlist才能接受得到
                例如:book_name=requeset.POST.getlist('checbox')
            多对多查询时,需要家伙加上all得到一个对象,然后可以循环,在加上属性能把值给取出来(在html文件中all不需要加上())
            关于多对多的增删改查
                先是在models中的创建
                #书籍列表
                class book(models.Model):
                    id=models.AutoField(primary_key=True)
                    title=models.CharField(max_length=32,null=False)
                    publisher = models.ForeignKey(to="publisher")
                    # author1 = models.ForeignKey(to="author", default=1)

                # 出版社表
                class publisher(models.Model):
                    id=models.AutoField(primary_key=True)
                    name=models.CharField(max_length=32,null=False)


                # 作者表(多对多)
                class author(models.Model):
                    id = models.AutoField(primary_key=True)
                    name = models.CharField(max_length=32, null=False)
                    # 与出版社多对多
                    book=models.ManyToManyField(to="book")
                下面只涉及多对多的增删改查
                增:
                    new_author_name = request.POST.get("author_name")
                    # post提交的数据是多个值的时候一定会要用getlist,如多选的checkbox和多选的select
                    books = request.POST.getlist("books")
                    # 创建作者
                    new_author_obj = models.Author.objects.create(name=new_author_name)
                    # 把新作者和书籍建立对应关系,自动提交
                    new_author_obj.book.set(books)
                    # 跳转到作者列表页面,查看是否添加成功!
                    这个相当于都增加了
                删:
                    delete_id = request.GET.get("id")
                    #根据ID值取到要删除的作者对象,直接删除
                    # 1. 去作者表把作者删了
                    # 2. 去作者和书的关联表,把对应的关联记录删除了
                    models.Author.objects.get(id=delete_id).delete()
                    # 返回作者列表页面
                改:
                    多对多一般是由数字对应起来的所以可直接将带有数字的列表进行设置
                    #找到对象
                    object=models.author.objects.get(id=1)
                    #修改对象
                    li=[1,2,3]
                    object.book.set(li)
                    object.save()
                    
                    在函数中
                    # 拿到提交过来的编辑后的数据
                    edit_author_id = request.POST.get("author_id")
                    new_author_name = request.POST.get("author_name")
                    # 拿到编辑后作者关联的书籍信息
                    new_books = request.POST.getlist("books")#getlist表示的得到的是多个值
                    # 根据ID找到当前编辑的作者对象
                    edit_author_obj = models.Author.objects.get(id=edit_author_id)
                    # 更新作者的名字
                    edit_author_obj.name = new_author_name
                    # 更新作者关联的书的对应关系
                    edit_author_obj.book.set(new_books)
                    # 将修改提交到数据库
                    edit_author_obj.save()
                    # 返回作者列表页,查看是否编辑成功

                查:
                    #查比较特殊,一般需要在html中取出相应的值,下面只是比较简单的模式
                    显示找到对应的对象
                    obj=models.author.objects.get(id=1)
                    #第一种
                    obj_list=obj.book.all()
                    for i in obj_list:
                        i.name
                    #第二种 
                        author=models.author.objects.get(id=1)
                        author_ele=author.book.get(id=1)
                        print(author_ele.title)
                    当查出来的的时候有多个时候,一定要加上all(),在html中的时候,需要去掉()。

原文地址:https://www.cnblogs.com/accolade/p/10696403.html