文章目录
官网:https://www.djangoproject.com/
博客:https://www.liujiangblog.com/
git:https://gitcode.net/mirrors/jackfrued/Python-100-Days
Django静态文件问题备注:
参考:
Django测试开发-20-settings.py中templates配置,使得APP下的模板以及根目录下的模板均可生效
解决django 多个APP时 static文件的问题
MVC架构中的“模型”和“视图”的解耦合。所谓“模型”就是数据(的表示),数据模型通常通过数据库实现持久化操作,而关系型数据库在过去和当下都是持久化的首选方案。
下面我们通过完成一个投票项目来讲解和模型相关的知识点。
投票项目的首页会展示某在线教育平台所有的学科;
点击学科可以查看到该学科的老师及其信息;
用户登录后在查看老师的页面为老师投票,可以投赞成票和反对票;
未登录的用户可以通过登录页进行登录;
尚未注册的用户可以通过注册页输入个人信息进行注册。
在这个项目中,我们使用MySQL数据库来实现数据持久化操作。
注意执行的位置,要在djangoproject的目录下执行
django-admin startapp polls
在templates目录下
登录页面login.html
注册页面register.html,
创建templates/polls目录。在polls目录下创建
展示学科的页面subjects.html
显示学科老师的页面teachers.html
具体内容下文进行描述。
create database vote default charset utf8;
create user 'django'@'%' identified by 'django123';
grant all privileges on vote.* to 'django'@'%';
flush privileges;
use vote;
-- 创建学科表
create table `tb_subject`
(
`no` integer auto_increment comment '学科编号',
`name` varchar(50) not null comment '学科名称',
`intro` varchar(1000) not null default '' comment '学科介绍',
`is_hot` boolean not null default 0 comment '是不是热门学科',
primary key (`no`)
);
-- 创建老师表
create table `tb_teacher`
(
`no` integer auto_increment comment '老师编号',
`name` varchar(20) not null comment '老师姓名',
`sex` boolean not null default 1 comment '老师性别',
`birth` date not null comment '出生日期',
`intro` varchar(1000) not null default '' comment '老师介绍',
`photo` varchar(255) not null default '' comment '老师照片',
`gcount` integer not null default 0 comment '好评数',
`bcount` integer not null default 0 comment '差评数',
`sno` integer not null comment '所属学科',
primary key (`no`),
foreign key (`sno`) references `tb_subject` (`no`)
);
在虚拟环境中安装连接MySQL数据库所需的依赖项。
pip install mysqlclient -i https://pypi.tuna.tsinghua.edu.cn/simple
修改项目的settings.py文件,首先将我们创建的应用polls添加已安装的项目(INSTALLED_APPS)中,然后配置MySQL作为持久化方案。
INSTALLED_APPS = [
# 新增polls
'polls',
]
DATABASES = {
'default': {
# 数据库引擎配置
'ENGINE': 'django.db.backends.mysql',
# 数据库的名字
'NAME': 'vote',
# 数据库服务器的IP地址(本机可以写localhost或127.0.0.1)
'HOST': 'localhost',
# 启动MySQL服务的端口号
'PORT': 3306,
# 数据库用户名和口令
'USER': 'django',
'PASSWORD': 'django123',
# 数据库使用的字符集
'CHARSET': 'utf8',
# 数据库时间日期的时区设定
'TIME_ZONE': 'Asia/Shanghai',
}
}
在配置ENGINE属性时,常用的可选值包括:sqlite3,postgresql,oracle,mysql
Django框架提供了ORM来解决数据持久化问题,ORM翻译成中文叫“对象关系映射”。利用Django的ORM,我们可以直接将刚才创建的学科表和老师表变成Django中的模型类。
python manage.py inspectdb > polls/models.py
在polls/models.py中生成如下代码,我们可以修改实体类,
from django.db import models
# Create your models here.
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# * Make sure each ForeignKey and OneToOneField has `on_delete` set to the desired behavior
# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
# 添加了注释部分verbose_name="名称"
class Subject(models.Model): # TbSubject 修改为 Subject
no = models.AutoField(primary_key=True,verbose_name="编号")
name = models.CharField(max_length=50,verbose_name="名称")
intro = models.CharField(max_length=1000,verbose_name="介绍")
is_hot = models.IntegerField(verbose_name="是否热门")
class Meta:
managed = False
db_table = 'tb_subject'
class Teacher(models.Model): # TbTeacher修改为Teacher
no = models.AutoField(primary_key=True,verbose_name="编号")
name = models.CharField(max_length=20,verbose_name="教师姓名")
sex = models.IntegerField(verbose_name="性别")
birth = models.DateField(verbose_name="出生年月")
intro = models.CharField(max_length=1000,verbose_name="个人介绍")
photo = models.CharField(max_length=255,verbose_name="照片")
good_count = models.IntegerField(db_column="gcount",verbose_name="好评数") # gcount 修改为good_count
bad_count= models.IntegerField(db_column="bcount",verbose_name="差评数") # bcount 修改为bad_count 添加db_column
subject = models.ForeignKey(Subject, models.DO_NOTHING, db_column='sno') # sno 修改为 subject, TbSubject修改为Subject
class Meta:
managed = False
db_table = 'tb_teacher'
在终端中输入下面的命令进入到Django项目的交互式环境,然后尝试对模型的操作。
python manage.py shell
from polls.models import Subject,Teacher
subject1 = Subject(name='Python全栈开发', intro='当下最热门的学科', is_hot=True)
subject1.save()
subject2 = Subject(name='全栈软件测试', intro='学习自动化测试的学科', is_hot=False)
subject2.save()
subject3 = Subject(name='JavaEE分布式开发', intro='基于Java语言的服务器应用开发', is_hot=True)
subject3.save()

subject = Subject.objects.get(no=1)
t1 = Teacher(name='甲1', sex="1",birth="2000-05-02",photo="照片路径",good_count="11",bad_count="0",intro='数学老师', subject=subject )
t1.save()

subject = Subject.objects.get(no=3)
t2 = Teacher(name='丙3', sex="2",birth="2000-05-02",photo="照片路径",good_count="11",bad_count="0",intro='语文老师', subject=subject )
t2.save()

subject = Subject.objects.get(no=1)
t3 = Teacher(name='丁4', sex="1",birth="2000-05-02",photo="照片路径",good_count="11",bad_count="0",intro='计算机老师', subject=subject )
t3.save()

subject = Subject.objects.get(no=2)
subject.delete()
# (1, {'polls.Subject': 1})
subject = Subject.objects.get(no=1)
subject.name = 'Python全栈+人工智能'
subject.save()

Subject.objects.all()
# <QuerySet [<Subject: Subject object (1)>, <Subject: Subject object (3)>]>
# 查询名称为“Python全栈+人工智能”的学科
Subject.objects.filter(name='Python全栈+人工智能')
# <QuerySet [<Subject: Subject object (1)>]>
# 查询名称包含“全栈”的学科(模糊查询)
Subject.objects.filter(name__contains='全栈')
# <QuerySet [<Subject: Subject object (1)>]>
Subject.objects.filter(name__startswith='全栈')
# <QuerySet []>
Subject.objects.filter(name__endswith='全栈')
# <QuerySet []>
# 查询所有热门学科
Subject.objects.filter(is_hot=True)
# <QuerySet [<Subject: Subject object (1)>, <Subject: Subject object (3)>]>
# 查询编号大于3小于10的学科
Subject.objects.filter(no__gt=3).filter(no__lt=10)
# <QuerySet []>
Subject.objects.filter(no__gt=3, no__lt=10)
# <QuerySet []>
# 查询编号在3到7之间的学科
Subject.objects.filter(no__gte=3, no__lte=7)
# <QuerySet [<Subject: Subject object (3)>]>
Subject.objects.filter(no__range=(3, 7))
# <QuerySet [<Subject: Subject object (3)>]>
# 查询主键为1的学科
Subject.objects.get(pk=1)
# <Subject: Subject object (1)>
Subject.objects.get(no=1)
# <Subject: Subject object (1)>
Subject.objects.filter(no=1).first()
# <Subject: Subject object (1)>
Subject.objects.filter(no=1).last()
# <Subject: Subject object (1)>
# 查询所有学科按编号升序排列
Subject.objects.order_by('no')
# <QuerySet [<Subject: Subject object (1)>, <Subject: Subject object (3)>]>
# 查询所有部门按部门编号降序排列
Subject.objects.order_by('-no')
# <QuerySet [<Subject: Subject object (3)>, <Subject: Subject object (1)>]>
# 按编号从小到大查询前3个学科
Subject.objects.order_by('no')[:3]
# <QuerySet [<Subject: Subject object (1)>, <Subject: Subject object (3)>]>
# 查询一共有多少个学科
Subject.objects.count()
# 2
# 查询编号为1的学科的老师
Teacher.objects.filter(subject__no=1)
# <QuerySet [<Teacher: Teacher object (1)>, <Teacher: Teacher object (3)>]>
Subject.objects.get(pk=1).teacher_set.all()
# Subject.objects.get(pk=1).teacher_set.all()
# 查询学科名称有“全栈”二字的学科的老师
Teacher.objects.filter(subject__name__contains='全栈')
# <QuerySet [<Teacher: Teacher object (1)>, <Teacher: Teacher object (3)>]>
说明1:由于老师与学科之间存在多对一外键关联,所以能通过学科反向查询到该学科的老师(从一对多关系中“一”的一方查询“多”的一方),反向查询属性默认的名字是类名小写_set(如上面例子中的teacher_set),当然也可以在创建模型时通过ForeingKey的related_name属性指定反向查询属性的名字。如果不希望执行反向查询可以将related_name属性设置为’+‘或者以’+'开头的字符串。
说明2:ORM查询多个对象时会返回QuerySet对象,QuerySet使用了惰性查询,即在创建QuerySet对象的过程中不涉及任何数据库活动,等真正用到对象时(对QuerySet求值)才向数据库发送SQL语句并获取对应的结果,这一点在实际开发中需要引起注意!
说明3:如果希望更新多条数据,不用先逐一获取模型对象再修改对象属性,可以直接使用QuerySet对象的update()方法一次性更新多条数据。
from django.shortcuts import render, redirect
from polls.models import Subject, Teacher
def show_subjects(request):
subjects = Subject.objects.all().order_by('no')
return render(request, 'polls/subjects.html', {'subjects': subjects})
def show_teachers(request):
try:
sno = int(request.GET.get('sno'))
teachers = []
if sno:
subject = Subject.objects.only('name').get(no=sno)
teachers = Teacher.objects.filter(subject=subject).order_by('no')
return render(request, 'polls/teachers.html', {
'subject': subject,
'teachers': teachers
})
except (ValueError, Subject.DoesNotExist):
return redirect('/')
接下来我们可以稍微对首页的代码进行调整,在页面的右上角显示出登录用户的用户名。我们将这段代码单独写成了一个名为polls/templates/header.html的HTML文件,首页中可以通过在<body>标签中添加{% include ‘header.html’ %}来包含这个页面,代码如下所示。
<div class="user">
{% if request.session.userid %}
<span>{{ request.session.username }}</span>
<a href="/logout">注销</a>
{% else %}
<a href="/login">登录</a>
{% endif %}
<a href="/register">注册</a>
</div>
subjects.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>学科信息</title>
<style>
#container {
width: 80%;
margin: 10px auto;
}
.user {
float: right;
margin-right: 10px;
}
.user>a {
margin-right: 10px;
}
#main>dl>dt {
font-size: 1.5em;
font-weight: bold;
}
#main>dl>dd {
font-size: 1.2em;
}
a {
text-decoration: none;
color: darkcyan;
}
</style>
</head>
<body>
{% include 'header.html' %}
<div id="container">
<!-- <div class="user">
<a href="/login">用户登录</a>
<a href="/register">快速注册</a>
</div> -->
<h1>XX学堂所有学科</h1>
<hr>
<a href="/excel">教师信息下载</a>
<div id="main">
{% for subject in subjects %}
<dl>
<dt>
<a href="/teachers/?sno={{ subject.no }}">{{ subject.name }}</a>
{% if subject.is_hot %}
<img src="/static/images/hot-icon-small.png">
{% endif %}
</dt>
<dd>{{ subject.intro }}</dd>
</dl>
{% endfor %}
</div>
</div>
</body>
</html>
teachers.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>老师信息</title>
<style>
#container {
width: 80%;
margin: 10px auto;
}
.teacher {
width: 100%;
margin: 0 auto;
padding: 10px 0;
border-bottom: 1px dashed gray;
overflow: auto;
}
.teacher>div {
float: left;
}
.photo {
height: 140px;
border-radius: 75px;
overflow: hidden;
margin-left: 20px;
}
.info {
width: 75%;
margin-left: 30px;
}
.info div {
clear: both;
margin: 5px 10px;
}
.info span {
margin-right: 25px;
}
.info a {
text-decoration: none;
color: darkcyan;
}
</style>
</head>
<body>
{% include 'header.html' %}
<a href="/get_echarts">教师好评分析</a>
<div id="container">
<h1>{{ subject.name }}学科的老师信息</h1>
<hr>
{% if not teachers %}
<h2>暂无该学科老师信息</h2>
{% endif %}
{% for teacher in teachers %}
<div class="teacher">
<div class="photo">
<img src="/static/images/{{ teacher.photo }}" height="140" alt="">
</div>
<div class="info">
<div>
<span><strong>姓名:{{ teacher.name }}</strong></span>
<span>性别:{{ teacher.sex | yesno:'男,女' }}</span>
<span>出生日期:{{ teacher.birth }}</span>
</div>
<div class="intro">{{ teacher.intro }}</div>
<div class="comment">
<a href="/praise/?tno={{ teacher.no }}">好评</a>
(<strong>{{ teacher.good_count }}</strong>)
<a href="/criticize/?tno={{ teacher.no }}">差评</a>
(<strong>{{ teacher.bad_count }}</strong>)
</div>
</div>
</div>
{% endfor %}
<a href="/">返回首页</a>
</div>
<script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
<script>
$(() => {
$('.comment>a').on('click', (evt) => {
evt.preventDefault()
let url = $(evt.target).attr('href')
$.getJSON(url, (json) => {
if (json.code == 20000) {
$(evt.target).next().text(json.count)
} else {
alert(json.mesg)
}
})
})
})
</script>
</body>
</html>
from django.contrib import admin
from django.urls import path
from polls import views as polls_views
urlpatterns = [
path('admin/', admin.site.urls),
path('', polls_views.show_subjects),
path('teachers/', polls_views.show_teachers),
]
到此为止,页面上需要的图片(静态资源)还没有能够正常展示,我们在下一章节中为大家介绍如何处理模板页上的需要的静态资源。
python manage.py runserver


本文主要是Django系列博客。本文是Django模型层models的使用过程。
1.创建数据库
2.创建表
3.按照MySQL依赖
4.修改settings.py文件,添加应用配置数据库
5.基于数据库生成实体类
6.使用shell完成CRUD操作
我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看rubyzip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d
很好奇,就使用rubyonrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提
我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我想用ruby编写一个小的命令行实用程序并将其作为gem分发。我知道安装后,Guard、Sass和Thor等某些gem可以从命令行自行运行。为了让gem像二进制文件一样可用,我需要在我的gemspec中指定什么。 最佳答案 Gem::Specification.newdo|s|...s.executable='name_of_executable'...endhttp://docs.rubygems.org/read/chapter/20 关于ruby-在Ruby中编写命令行实用程序
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss
我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢
我正在编写一个小脚本来定位aws存储桶中的特定文件,并创建一个临时验证的url以发送给同事。(理想情况下,这将创建类似于在控制台上右键单击存储桶中的文件并复制链接地址的结果)。我研究过回形针,它似乎不符合这个标准,但我可能只是不知道它的全部功能。我尝试了以下方法:defauthenticated_url(file_name,bucket)AWS::S3::S3Object.url_for(file_name,bucket,:secure=>true,:expires=>20*60)end产生这种类型的结果:...-1.amazonaws.com/file_path/file.zip.A