毕设-Django—Python一些记录

前言

用来记一下毕设用到的坑,说不定以后用到的时候方便查查

Django模型修改及数据迁移

Migrations

Django中对Model进行修改是件麻烦的事情,syncdb命令仅仅创建数据库里还没有的表,它并不对已存在的数据表进行同步修改,也不处理数据模型的删除。 如果你新增或修改数据模型里的字段,或是删除了一个数据模型,你需要手动在数据库里进行相应的修改或者使用South。Django 1.7中已经集成了South的代码,提供了3个新命令:

  • migrate: 用于执行迁移动作,具有syncdb的功能
  • makemigrations: 基于当前的model创建新的迁移策略文件
  • sqlmigrate: 显示迁移的SQL语句,具有sqlall的功能

使用起来很简单,对Model做了修改后,使用makemigrations记录修改:

1
2
3
4
$ python manage.py makemigrations
Migrations for 'books':
0003_auto.py:
- Alter field author on book

你的Model会被扫描, 然后与migrations文件夹中以前的版本作比较, 然后生成本次迁移文件。

有了新的migration文件,就可以使用migrate修改数据库模式:

1
2
3
4
5
6
7
8
9
10
11
$ python manage.py migrate
Operations to perform:
Synchronize unmigrated apps: sessions, admin, messages, auth, staticfiles, contenttypes
Apply all migrations: books
Synchronizing apps without migrations:
Creating tables...
Installing custom SQL...
Installing indexes...
Installed 0 object(s) from 0 fixture(s)
Running migrations:
Applying books.0003_auto... OK

也可以针对单独的app生成migration:

1
$ python manage.py makemigrations your_app_label

也可以对数据库中的数据进行修改,首先建立一个空的migration文件:

1
2
python manage.py makemigrations ``-``-``empty yourappname
migrations

文件的内容如下:

1
2
3
4
5
6
7
8
9
10
11
# -*- coding: utf-8 -*-
from django.db import models, migrations

class Migration(migrations.Migration):

dependencies = [
('yourappname', '0001_initial'),
]

operations = [
]

如果想修改某个Model例如Person的数据,设置其name字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# -*- coding: utf-8 -*-
from django.db import models, migrations

def combine_names(apps, schema_editor):
# We can't import the Person model directly as it may be a newer
# version than this migration expects. We use the historical version.
Person = apps.get_model("yourappname", "Person")
for person in Person.objects.all():
person.name = "%s %s" % (person.first_name, person.last_name)
person.save()

class Migration(migrations.Migration):

dependencies = [
('yourappname', '0001_initial'),
]

operations = [
migrations.RunPython(combine_names),
]

最后运行 python manage.py migrate即可。这样Person中的所有对象的name字段都设置好了。

依据Model修改关系数据库是开发中的一个重要的问题,解决这个问题可以提升开发速度,不过要在生产环境中随便使用migrate操作数据库还是很危险的,有时候需要手动修改数据库。

手动修改数据库

当处理模型修改的时候:

  • 如果模型包含一个未曾在数据库里建立的字段,Django会报出错信息。 当你第一次用Django的数据库API请求表中不存在的字段时会导致错误。

  • Django不关心数据库表中是否存在未在模型中定义的列。

  • Django不关心数据库中是否存在未被模型表示的table。

添加字段

  1. 在你的模型里添加字段。下例向Book模型添加num_pages字段:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class Book(models.Model):
    title = models.CharField(max_length=100)
    authors = models.ManyToManyField(Author)
    publisher = models.ForeignKey(Publisher)
    publication_date = models.DateField()
    **num_pages = models.IntegerField(blank=True, null=True)**

    def __unicode__(self):
    return self.title 

  2. 运行manage.py sqlall yourappname来测试模型新的CREATE TABLE语句。

    1
    2
    3
    4
    5
    6
    7
    CREATE TABLE "books_book" (
    "id" serial NOT NULL PRIMARY KEY,
    "title" varchar(100) NOT NULL,
    "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id"),
    "publication_date" date NOT NULL,
    "num_pages" integer NULL
    );
  3. 开启你的数据库的交互命令界面(比如,psql或者mysql,或者可以使用manage.py dbshell。 执行ALTER TABLE语句来添加新列。

    ALTER TABLE books_book ADD COLUMN num_pages integer;

添加 非NULL 字段

先创建 NULL 型的字段,然后将该字段的值填充为某个默认值,然后再将该字段改为 NOT NULL 型

1
2
3
4
5
BEGIN;
ALTER TABLE books_book ADD COLUMN num_pages integer;
UPDATE books_book SET num_pages=0;
UPDATE books_book SET num_pages = NULL;
COMMIT;

或者

1
ALTER TABLE <YourTable> ADD <NewColumn> <NewColumnType> NOT NULL DEFAULT <DefaultValue>;

添加ForeignKey或ManyToManyField

添加外键即是添加key_id的integer字段,添加多对多字段是创建一个新的数据表。

删除字段

比较简单,将表中的某列删掉即可

1
ALTER TABLE books_book DROP COLUMN num_pages;

使用sqlite3时,会有些麻烦,sqlite3不支持删除列操作,只有有限地 ALTER TABLE 支持。你可以使用它来在表的末尾增加一列,可更改表的名称。 如果需要对表结构做更复杂的改变,则必须重新建表。重建时可以先将已存在的数据放到一个临时表中,删除原表, 创建新表,然后将数据从临时表中复制回来。

如,假设有一个 t1 表,其中有 “a”, “b”, “c” 三列, 如果要删除列 c :

1
2
3
4
5
6
7
8
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;

删除多对多关联字段

删掉多对多关联的数据表即可

1
DROP TABLE books_book_authors;

删除模型

删除数据表即可

1
DROP TABLE books_book;

数据迁移

django 项目提供了一个导出的方法 python manage.py dumpdata, 不指定 appname 时默认为导出所有的app

1
python manage.py dumpdata myapp > myapp.json

导出的文件内容格式:

1
2
3
4
5
6
7
8
BEGIN TRANSACTION;
CREATE TEMPORARY TABLE t1_backup(a,b);
INSERT INTO t1_backup SELECT a,b FROM t1;
DROP TABLE t1;
CREATE TABLE t1(a,b);
INSERT INTO t1 SELECT a,b FROM t1_backup;
DROP TABLE t1_backup;
COMMIT;

数据导入:

1
python manage.py loaddata myapp.json

导出用户数据:

1
python manage.py dumpdata auth > auth.json

来源:https://www.cnblogs.com/linxiyue/p/4106514.html

python 获取当前路径

1
2
3
4
5
6
7
8
import sys,os   # sys 对解释器操作(命令)的内置模块   # os 对操作系统操作(命令)的内置模块
# __file__ 为当前脚本, 形如 xxx.py
# os.path.abspath(__file__) 获取当前脚本的绝对路径(相对于执行该脚本的终端)
# os.path.dirname() 获取上级目录
# 下面嵌套了两次,即得到 父目录 的 父目录 ;同理可根据自己的需求来获取相应的目录
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# 将BASE_DIR路径添加到解释器的搜索路径列表中
sys.path.append(BASE_DIR)

request包消除ssl验证,强制ipv4

1
2
3
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
requests.packages.urllib3.disable_warnings(InsecurePlatformWarning)
requests.packages.urllib3.util.connection.HAS_IPV6 = False

windows获取当前路径

1
2
3
4
5
6
7
8
import sys,os   # sys 对解释器操作(命令)的内置模块   # os 对操作系统操作(命令)的内置模块
# __file__ 为当前脚本, 形如 xxx.py
# os.path.abspath(__file__) 获取当前脚本的绝对路径(相对于执行该脚本的终端)
# os.path.dirname() 获取上级目录
# 下面嵌套了两次,即得到 父目录 的 父目录 ;同理可根据自己的需求来获取相应的目录
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
# 将BASE_DIR路径添加到解释器的搜索路径列表中
sys.path.append(BASE_DIR)

django模型类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
1、models.AutoField

自增列 = int(11)
如果没有的话,默认会生成一个名称为 id 的列
如果要显式的自定义一个自增列,必须设置primary_key=True。
2、models.CharField

字符串字段
必须设置max_length参数
3、models.BooleanField

布尔类型=tinyint(1)
不能为空,可添加Blank=True
4、models.ComaSeparatedIntegerField

用逗号分割的数字=varchar
继承CharField,所以必须 max_lenght 参数
5、models.DateField

日期类型 date
DateField.auto_now:保存时自动设置该字段为现在日期,最后修改日期
DateField.auto_now_add:当该对象第一次被创建是自动设置该字段为现在日期,创建日期。
6、models.DateTimeField

日期时间类型 datetime
同DateField的参数
7、models.Decimal

十进制小数类型 = decimal
DecimalField.max_digits:数字中允许的最大位数
DecimalField.decimal_places:存储的十进制位数
8、models.EmailField

一个带有检查 Email 合法性的 CharField
9、models.FloatField

浮点类型 = double
10、models.IntegerField

整形
11、models.BigIntegerField

长整形
integer_field_ranges = {
'SmallIntegerField': (-32768, 32767),

'IntegerField': (-2147483648, 2147483647),

'BigIntegerField': (-9223372036854775808, 9223372036854775807),

'PositiveSmallIntegerField': (0, 32767),

'PositiveIntegerField': (0, 2147483647),

}

12、models.GenericIPAddressField

一个带有检查 IP地址合法性的 CharField
13、models.NullBooleanField

允许为空的布尔类型
14、models.PositiveIntegerFiel

正整数
15、models.PositiveSmallIntegerField

正smallInteger
16、models.SlugField

减号、下划线、字母、数字
17、models.SmallIntegerField

数字
数据库中的字段有:tinyint、smallint、int、bigint
18、models.TextField

大文本。默认对应的form标签是textarea。
19、models.TimeField

时间 HH:MM[:ss[.uuuuuu]]
20、models.URLField

一个带有URL合法性校验的CharField。
21、models.BinaryField

二进制
存储二进制数据。不能使用filter函数获得QuerySet。
22、models.ImageField

图片
ImageField.height_field、ImageField.width_field:如果提供这两个参数,则图片将按提供的高度和宽度规格保存。
该字段要求 Python Imaging 库Pillow。
会检查上传的对象是否是一个合法图片。
23、models.FileField(upload_to=None[, max_length=100, ** options])

文件
FileField.upload_to:一个用于保存上传文件的本地文件系统路径,该路径由 MEDIA_ROOT 中设置
这个字段不能设置primary_key和unique选项.在数据库中存储类型是varchar,默认最大长度为100
24、models.FilePathField(path=None[, math=None, recursive=False, max_length=100, **options])

FilePathField.path:文件的绝对路径,必填

FilePathField.match:用于过滤路径下文件名的正则表达式,该表达式将用在文件名上(不包括路径)。

FilePathField.recursive:True 或 False,默认为 False,指定是否应包括所有子目录的路径。

例如:FilePathField(path="/home/images", match="foo.*", recursive=True)

链接:https://www.jianshu.com/p/a7dba55a62b5

django模板切片,循环

1
{% for p_var in ipinfotest1.port_set.all|slice:"3" %}

html隐藏表单

1
<input name="search" type="hidden" value="{{ search }}">

python redis

(11条消息) Python操作Redis详解_csdnhxs的博客-CSDN博客_python redis

lrem函数改动,直接看源码吧

1
2
3
4
5
6
7
8
9
def lrem(self, name: str, count: int, value: str) -> Union[Awaitable[int], int]:
"""
Remove the first ``count`` occurrences of elements equal to ``value``
from the list stored at ``name``.

The count argument influences the operation in the following ways:
count > 0: Remove elements equal to value moving from head to tail.
count < 0: Remove elements equal to value moving from tail to head.
count = 0: Remove all elements equal to value.

前端form表单

1
2
3
4
5
6
7
8
9
10
<form action="/pagetest/" method="get">
<div class="input-group">
<input type="text" value="{{ searchshow }}" placeholder="{{ searchshow }}" name="search" class="form-control input-lg">
<div class="input-group-btn">
<button class="btn btn-lg btn-primary" type="submit">
搜索
</button>
</div>
</div>
</form>

前端js get请求 jquery

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script type="text/javascript">
function deletePost(){
$.ajax({
type:"GET",
url:"/../stoptask/",
data:{"taskname":"{{taskname}}"},
async:true,
cache:true,
dataType:"text",
success:function (backdata,status,xmlHttpRequest) {
swal("服务器返回的数据"+backdata+"\n服务器响应的状态"+status+"\n服务器请求"+xmlHttpRequest+"\n状态码"+xmlHttpRequest.status+"\nresponseText:"+xmlHttpRequest.responseText,'success');
},
error:function (msg) {
alert("错误内容"+msg)
}
});


}

</script>

点击按钮事件

1
2
3
4
<div class="modal-footer" onclick="deletePost()">
<button type="button" class="btn btn-default" data-dismiss="modal">返回</button>
<button type="button" class="btn btn-primary" data-dismiss="modal" id="btnOkDelete">确认</button>
</div>

swal sweetalert.js使用

1
2
3
4
5
6
7
8
9
10
11
12
13
//弹出框提醒
swal({
title: "111",
text: "111...",
icon: "success",
buttons: false,
timer: 4000,
});
//动画过渡完跳转
setTimeout(function(){
window.location.href="https://www.baidu.com";
return false;
},1000);

删除 django 数据

1
2
delete_tag = tag.filter(tagergetname=tagname)
delete_tag.delete()

django QuerySet 类型转字典

QuerySet 类型转字典 - 简书 (jianshu.com)

django 登录用户/鉴权

在需要登录的视图加这个装饰器,/login是登录使用的url,需要再写一个视图函数

1
@login_required(login_url="/login")

在视图界面导入这些库

1
2
3
4
from django.contrib.auth import authenticate, login, logout
from django.core.paginator import Paginator
from django.shortcuts import render, redirect, reverse
from django.contrib.auth.decorators import login_required

request.user.is_authenticated可以获取当前是否登录了用户,可以先看看是否已经算登录了用户,被坑过

模板获取登录用户

1
2
3
4
5
6
7
8
9
 {% if user.is_authenticated %}
<ul class="nav navbar-top-links navbar-right">
<li>
<a href="/loginout">
<i class="fa fa-sign-out"></i> 登出用户 {{ user.get_username }}
</a>
</li>
</ul>
{% endif %}

如何通过js获取输入框内容

例如我们页面上定义了一个输入框:

<input type="text" name="message" id="message" placeholder="请输入" />

JavaScript:
var value = document.getElementById("message").value

jQuery:
var value = $('#message').val();

原文链接:https://blog.csdn.net/qq_22331931/article/details/105210289

django 批量更新数据

使用bulk_update()方法

1
2
3
4
5
6
for ipinfovar in ipinfotest:
ipinfovar.assettag = assettag
#ipinfotest = list(ipinfotest)
#ipinfoupdata = [ ipinfovar.assettag = assettag for ipinfovar in ipinfotest]
#ipinfoupdata = ipinfotest.create(assettag=assettag)
ipinfo.objects.bulk_update(ipinfotest,['assettag'])

本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!,本博客仅用于交流学习,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。 文章作者拥有对此站文章的修改和解释权。如欲转载此站文章,需取得作者同意,且必须保证此文章的完整性,包括版权声明等全部内容。未经文章作者允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。若造成严重后果,本人将依法追究法律责任。 阅读本站文章则默认遵守此规则。