一.模型继承
1.概述
默认一个模型在数据库中映射一张表
如果模型存在继承的时候,父模型产生表映射
子模型对应的表会通过外键和父表产生关联
从表外键引用主表得主键
不能说从表外键引用主表的主键就一定是模型继承,因为一对一、一对多,都会引用主表的主键
关系型数据库性能
数据量越大性能越低
关系越多越复杂越低性能越低
2.模型创建
class Dog(Animal):
name = models.CharField(max_length=32)
type = models.CharField(max_length=16)
class Meta:
db_table = 'dog'
class Cat(Animal):
name = models.CharField(max_length=32)
color = models.CharField(max_length=16)
class Meta:
db_table = 'cat'
上面创建模型时,有重复的属性,当有重复的属性的时候,我们应该想到模型的继承。
# 模型继承的意思,就是公用某一些属性,但是并不是想降低效率
class AnimalModel(models.Model):
name = models.CharField(max_length=32)
class Meta:
abstract = True
class Dog(AnimalModel):
type = models.CharField(max_length=16)
class Meta:
db_table = 'dog'
class Cat(AnimalModel):
color = models.CharField(max_length=16)
class Meta:
db_table = 'cat'
创建主路由:
url(r'^com/',include('ComApp.urls')),
创建子路由:
url(r'^addDog/',views.addDog),
url(r'^addCat/',views.addCat),
生成视图函数:
def addDog(request):
dog = Dog()
dog.type = '二哈'
dog.name = '哈王'
dog.save()
return HttpResponse('添加小狗成功')
def addCat(request):
cat = Cat()
cat.color = '白色'
cat.name = '秀秀'
cat.save()
return HttpResponse('添加小猫成功')
运行结果:
抽象模型
在父类的Model的元信息中添加 abstract=True
class Meta:
abstract=True
抽象的模型不会在数据库中产生表
子模型拥有父模型中的所有字段
二.静态资源
1.静态资源和模板的区别
(1)模板的路径不可以直接访问,必须通过请求来访问
static资源可以直接访问
创建子路由:
url(r'^testTem/',views.testTem),
生成视图函数:
def testTem(request):
return render(request,'testTem.html')
创建模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
欢迎来到英雄联盟
</body>
</html>
运行结果:
若直接访问:
创建static包,创建testStatic页面:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
欢迎来到王者荣耀
</body>
</html>
在settings.py文件中进行static配置:
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]
运行结果:
(2)模板的语法不可以在静态资源中书写
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
欢迎来到王者荣耀
{% for foo in fuc %}
{% endfor %}
</body>
</html>
运行结果:
2.注意
(1)使用的时候注意先配置资源位置:
STATICFILES_DIRS = [
os.path.join(BASE_DIR,'static')
]
使用 {% load static %}
{% static ‘相对路径’ %}
使用详情请看我之前的博文:Django模板中的加载静态资源
(2)全栈工程师:要求会templates
开发工程师:前后端分离static
三.文件上传
要求:客户端
必须使用POST
指定enctype='multiplepart/form-data'
1.源码实现
修改主路由:
url(r'^com/',include('ComApp.urls',namespace='com')),
创建子路由:
url(r'^testUpload/',views.testUpload,name='testUpload'),
生成视图函数:
def testUpload(request):
if request.method == 'GET':
return render(request,'testUpload.html')
elif request.method == 'POST':
icon = request.FILES.get('icon')
return HttpResponse('上传成功'
创建testUpload.html模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>上传图片</h1>
<form action="{% url 'com:testUpload' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="icon">
<button>上传</button>
</form>
</body>
</html>
运行结果:
接下来设置文件存放位置:
在static下创建upload包放置一张图片:
视图函数:
def testUpload(request):
if request.method == 'GET':
return render(request,'testUpload.html')
elif request.method == 'POST':
icon = request.FILES.get('icon')
# 因为我们使用的是windows连接的远程服务器,那么这个时候就不可以使用绝对路径
# 绝对路径windows和centos的路径不一致,上传或者下载的路径就都不对,所以如果使用的是远程服务器,那么就要写相对路径
with open('static/upload/1.jpg','wb')as fp:
for part in icon.chunks():
fp.write(part)
# 103个字节
# 针对文件操作,默认with open是自带close的
# 原来是close中封装了flush方法,但是现在文件操作中,已经没有flush方法了,因为close方法中只有pass
fp.flush()
return HttpResponse('上传成功')
重新上传新的文件:
2.Django文件上传
创建子路由:
url(r'^testDjangoUpload/',views.testDjangoUpload,name="testDjangoUpload"),
创建模型:
class User(models.Model):
u_name = models.CharField(max_length=32)
u_icon = models.ImageField(upload_to='%Y/%m/%d/icons')
class Meta:
db_table = 'user'
生成视图函数:
def testDjangoUpload(request):
if request.method == 'GET':
return render(request,'testDjangoUpload.html')
elif request.method == 'POST':
icon = request.FILES.get('icon')
user = User()
user.u_name = '动漫人物'
user.u_icon = icon
user.save()
return HttpResponse('上传成功')
在settings中设置MEDIA_ROOT:
MEDIA_ROOT = os.path.join(BASE_DIR,'static/uploadDjango')
创建模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>django的文件上传</h1>
<form action="{% url 'com:testDjangoUpload' %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="icon">
<button>上传</button>
</form>
</body>
</html>
运行结果:
出现上面的错误是没有安装pillow,我们需进行安装:pip install pillow,再次运行:
点击前:
点击后:
Django的文件上传步骤:
1 执行一个请求,跳转到一个页面
2 页面中的请求方式是post,然后设置enctype
3 在settings中设置MEDIA_ROOT: os.path.join(BASE_DIR,‘static/自定义文件夹名字’)
4 创建一个模型,模型中一个属性的类型是imageFiled,该属性的约束是upload_to
注意imageFiled依赖于pillow,必须安装,如果你的django版本自动添加了pillow,就不需要安装
注意文件图片保存的位置是MEDIA_ROOT和upload_to的拼接
5 实例化对象,保存即可
注意:
1:重复添加同一个图片,那么会直接添加进去,文件的名字是文件名原名+唯一串
2:数据库icon的值是upload_to + 文件名字
隐藏bug:linux系统下文件夹的第一级子目录下,最多存储65535个文件
解决方案:u_icon = models.ImageField(upload_to=’%Y/%m/%d/icons’)
支持时间格式化:%Y%m%d%H%M%S
3.显示图片
创建子路由:
url(r'^getImage/',views.getImage),
生成视图函数:
def getImage(request):
user = User.objects.last()
context = {
'icon':user.u_icon
}
return render(request,'getImage.html',context=context)
创建模板:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
img{
width: 80px;
height: 80px;
border-radius: 50%;
}
</style>
</head>
<body>
<img src="/static/uploadDjango/{{ icon }}" alt="">
</body>
</html>
运行结果: