有需要上网现查现学的东西。
django.core.paginator
模块中。Paginator 对象的 page () 方法返回 Page 对象
page = paginator.page(页码)
object_list:当前页上所有数据对象的列表
number:当前页的序号,从 1 开始
paginator:当前 page 对象相关的 Paginator 对象
has_next ():如果有下一页返回 True
has_previous ():如果有上一页返回 True
has_other_pages ():如果有上一页或下一页返回 True
next_page_number ():返回下一页的页码,如果下一页不存在,抛出 InvalidPage 异常
previous_page_number ():返回上一页的页码,如果上一页不存在,抛出 InvalidPage 异常
len ():返回当前页面对象的个数
Page 对象是可迭代对象,可以用 for 语句来 访问当前页面中的每个对象
视图函数
from django.core.paginator import Paginato
def book(request):
bks = Book.objects.all()
paginator = Paginator(bks, 10)
cur_page = request.GET.get('page', 1) # 得到默认的当前页
page = paginator.page(cur_page)
return render(request, 'bookstore/book.html', locals())
模板设计
<html>
<head>
<title>分页显示</title>
</head>
<body>
{% for b in page %}
<div>{{ b.title }}</div>
{% endfor %}
{% if page.has_previous %}
<a href="{% url 'book' %}?page={{ page.previous_page_number }}">上一页</a>
{% else %}
上一页
{% endif %}
{% for p in paginator.page_range %}
{% if p == page.number %}
{{ p }}
{% else %}
<a href="{% url 'book' %}?page={{ p }}">{{ p }}</a>
{% endif %}
{% endfor %}
{% if page.has_next %}
<a href="{% url 'book' %}?page={{ page.next_page_number }}">下一页</a>
{% else %}
下一页
{% endif %}
</body>
</html>
Django可直接在视图函数中生成csv文件 并响应给浏览器
import csv
from django.http import HttpResponse
from .models import Book
def make_csv_view(request):
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="mybook.csv"'
all_book = Book.objects.all()
writer = csv.writer(response)
writer.writerow(['id', 'title'])
for b in all_book:
writer.writerow([b.id, b.title])
return response
Content-Disposition
标头,其中包含CSV文件的名称。它将被浏览器用于“另存为…”对话框writer.writerow
,传递一个可迭代对象,如列表或元组。名字 xxx 对应 request.FILES['xxx'] 对应的内存缓冲文件流对象。可通能过 request.FILES['xxx'] 返回的对象获取上传文件数据
file=request.FILES['xxx'] file 绑定文件流对象,可以通过文件流对象的如下信息获取文件数据
file.name 文件名
file.file 文件的字节流数据
<!-- file: index/templates/index/upload.html -->
<html>
<head>
<meta charset="utf-8">
<title>文件上传</title>
</head>
<body>
<h3>上传文件</h3>
<form method="post" action="/test_upload" enctype="multipart/form-data">
<input type="file" name="myfile"/><br>
<input type="submit" value="上传">
</form>
</body>
</html>
# file : settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
$ mkdir media
# file views.py
from django.http import HttpResponse
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
import os
@csrf_exempt
def upload_view(request):
if request.method == 'GET':
return render(request, 'test_upload.html')
elif request.method == "POST":
a_file = request.FILES['myfile']
print("上传文件名是:", a_file.name)
filename =os.path.join(settings.MEDIA_ROOT, a_file.name)
with open(filename, 'wb') as f:
data = a_file.file.read()
f.write(data)
return HttpResponse("接收文件:" + a_file.name + "成功")
#test_upload/models.py
from django.db import models
# Create your models here.
class Content(models.Model):
desc = models.CharField(max_length=100)
myfile = models.FileField(upload_to='myfiles')
#test_upload/views.py
from test_upload.models import *
from django.views.decorators.csrf import csrf_exempt
@csrf_exempt
def upload_view_dj(request):
if request.method == 'GET':
return render(request, 'test_upload.html')
elif request.method == 'POST':
title = request.POST['title']
a_file = request.FILES['myfile']
Content.objects.create(desc=title,myfile=a_file)
return HttpResponse('----upload is ok-----')
from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
浏览器可以访问 http://127.0.0.1:8000/media/xxxx
from django.contrib.auth.models import User
创建普通用户 create_use
from django.contrib.auth.models import Use
user = User.objects.create_user(username='用户名', password='密码', email='邮箱',...)
from django.contrib.auth.models import Use
user = User.objects.create_superuser(username='用户名', password='密码', email='邮箱',...)
from django.contrib.auth.models import Use
try:
user = User.objects.get(username='用户名')
user.is_active = False # 记当前用户无效
user.save()
print("删除普通用户成功!")
except:
print("删除普通用户失败")
from django.contrib.auth.models import Use
try:
user = User.objects.get(username='xiaonao')
user.set_password('654321')
user.save()
return HttpResponse("修改密码成功!")
except:
return HttpResponse("修改密码失败!")
from django.contrib.auth.models import Use
try:
user = User.objects.get(username='xiaonao')
if user.check_password('654321'): # 成功返回True,失败返回False
return HttpResponse("密码正确")
else:
return HttpResponse("密码错误")
except:
return HttpResponse("没有此用户!")
如果需要在默认auth表上扩展新的字段,如phone
#models.py案例
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class UserInfo(AbstractUser):
phone = models.CharField(max_length=11, default='')
#settings.py添加配置
AUTH_USER_MODEL = 'user.UserInfo'
#添加用户
from user.models import UserInfo
UserInfo.objects.create_user(username='guoxiao', password='123456', phone='13488871101')
QQ邮箱->设置->帐户->“POP3/IMAP......服务”
settings.py
设置# 发送邮件设置
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' # 固定写法
EMAIL_HOST = 'smtp.qq.com' # 腾讯QQ邮箱 SMTP 服务器地址
EMAIL_PORT = 25 # SMTP服务的端口号
EMAIL_HOST_USER = 'xxxx@qq.com' # 发送邮件的QQ邮箱
EMAIL_HOST_PASSWORD = '******' # 在QQ邮箱->设置->帐户->“POP3/IMAP......服务” 里得到的在第三方登录QQ邮箱授权码
EMAIL_USE_TLS = True # 与SMTP服务器通信时,是否启动TLS链接(安全链接)默认false
视图函数中
from django.core import mail
mail.send_mail(
subject, #题目
message, # 消息内容
from_email, # 发送者[当前配置邮箱]
recipient_list=['xxx@qq.com'], # 接收者邮件列表
)
在安装机器上安装和配置同版本的环境
sudo scp /home/tarena/django/mysite1 root@88.77.66.55:/home/root/xxx
请输入root密码:
3. 用 uwsgi 替代 python3 manage.py runserver 方法启动服务器
4. 配置 nginx 反向代理服务器
5.用 nginx 配置静态文件路径,解决静态路径问题
uWSGI 网关接口配置 (ubuntu 18.04 配置)
终端输入如下命令
sudo pip3 install uwsgi==2.0.18 -i https://pypi.tuna.tsinghua.edu.cn/simple/
检查是否安装成功
sudo pip3 freeze|grep -i 'uwsgi'
#如果成功安装,则会输出
uWSGI==2.0.18
如: mysite1/mysite1/uwsgi.ini
[uwsgi]
# 套接字方式的 IP地址:端口号
# socket=127.0.0.1:8000
# Http通信方式的 IP地址:端口号
http=127.0.0.1:8000
# 项目当前工作目录
chdir=/home/tarena/.../my_project 这里需要换为项目文件夹的绝对路径
# 项目中wsgi.py文件的目录,相对于当前工作目录
wsgi-file=my_project/wsgi.py
# 进程个数
process=4
# 每个进程的线程个数
threads=2
# 服务的pid记录文件
pidfile=uwsgi.pid
# 服务的目志文件位置
daemonize=uwsgi.log
# 开启主进程管理模式
master=true
启动 uwsgi
$ 进入到项目同名文件夹下 【即settings.py所在目录】
$ sudo uwsgi --ini uwsgi.ini
停止 uwsgi
$ 进入到项目同名文件夹下 【即settings.py所在目录】
$ sudo uwsgi --stop uwsgi.pid
说明:
ps aux|grep 'uwsgi' -> 查看uwsgi进程
tarena 103408 0.0 0.9 137172 39984 ? S 10:02 0:01 uwsgi --ini uwsgi.ini
tarena 103410 0.0 0.9 436200 38552 ? Sl 10:02 0:00 uwsgi --ini uwsgi.ini
ps -ef | grep 'uwsgi' | grep -v grep | awk '{print $2}' | xargs sudo kill -9
测试:
nginx 及反向代理配置
vim /etc/apt/sources.list
更改国内源
sudo apt-get update
# 在server节点下添加新的location项,指向uwsgi的ip与端口。
server {
...
location / {
uwsgi_pass 127.0.0.1:8000; # 重定向到127.0.0.1的8000端口
include /etc/nginx/uwsgi_params; # 将所有的参数转到uwsgi下
}
...
}
nginx 服务控制
SHELL
1
2
3
$ sudo /etc/init.d/nginx start|stop|restart|status
# 或
$ sudo service nginx start|stop|restart|status
通过 start,stop,restart,status 可能实现 nginx 服务的启动、停止、重启、操作
修改项目同名文件夹/uwsgi.ini 下的 Http 通信方式改为 socket 通信方式
[uwsgi]
# 去掉如下
# http=127.0.0.1:8000
# 改为
socket=127.0.0.1:8000
进入到 项目同名文件夹下
$ sudo uwsgi --stop uwsgi.pid
$ sudo uwsgi --ini uwsgi.ini
测试:
在浏览器端输入 http://127.0.0.1 进行测试
注意 :
1,此时端口号为 80 (nginx 默认值)
2,Django 中有任何修改 需要重启 uwsgi , 否则修改不生效
nginx 配置静态文件路径
STATIC_ROOT = '/home/tarena/项目名_static/static
#注意 此配置路径为 存放所有正式环境中需要的静态文件
# file : /etc/nginx/sites-enabled/default
# 新添加location /static 路由配置,重定向到指定的 第一步创建的路径即可
server {
...
location /static {
# root 第一步创建文件夹的绝对路径,如:
root /home/tarena/项目名_static;
}
...
}
404/500 界面
from django.http import Http404
def xxx_view( ):
raise Http404 # 直接返回404
报错邮件中会显示一些错误的追踪,这些错误追踪中会出现如 password等敏感信息,Django已经将配置文件中的敏感信息 过滤修改为 多个星号,但是用户自定义的视图函数需要用户手动过滤敏感信息
1,视图函数中的局部变量
from django.views.decorators.debug import sensitive_variables
@sensitive_variables('user', 'pw', 'cc')
def process_info(user):
pw = user.pass_word
cc = user.credit_card_number
name = user.name
...
#注意:
#1 若报错邮件中牵扯到user,pw,cc等局部变量的值,则会将其替换成 *****, 而 name 变量还显示其真实值
#2 多个装饰器时,需要将其放在最顶部
#3 若不传参数,则过滤所有局部变量的值
2,POST提交中的数据
from django.views.decorators.debug import sensitive_post_parameters
@sensitive_post_parameters('password', 'username')
def index(request):
s = request.POST['username'] + request.POST['abcd']
#'abcd' 并不存在,此时引发error
#POST中 username 及 password的值会被替换成 ******