Django简介
Django是一个基于MVC构造的框架。但是在Django中,控制器接受用户输入的部分由框架自行处理,所以 Django 里更关注的是模型(Model)、模板(Template)和视图(Views),称为 MTV模式。它们各自的职责如下:
| 层次 | 职责 |
| 模型(Model),即数据存取层 | 处理与数据相关的所有事务: 如何存取、如何验证有效性、包含哪些行为以及数据之间的关系等。 |
| 模板(Template),即业务逻辑层 | 处理与表现相关的决定: 如何在页面或其他类型文档中进行显示。 |
| 视图(View),即表现层 | 存取模型及调取恰当模板的相关逻辑。模型与模板的桥梁。 |
从以上表述可以看出Django 视图不处理用户输入,而仅仅决定要展现哪些数据给用户,而Django 模板 仅仅决定如何展现Django视图指定的数据。或者说, Django将MVC中的视图进一步分解为 Django视图 和 Django模板两个部分,分别决定 “展现哪些数据” 和 “如何展现”,使得Django的模板可以根据需要随时替换,而不仅仅限制于内置的模板。
至于MVC控制器部分,由Django框架的URLconf来实现。URLconf机制是使用正则表达式匹配URL,然后调用合适的Python函数。URLconf对于URL的规则没有任何限制,你完全可以设计成任意的URL风格,不管是传统的,RESTful的,或者是另类的。框架把控制层给封装了,无非与数据交互这层都是数据库表的读,写,删除,更新的操作。在写程序的时候,只要调用相应的方法就行了,感觉很方便。程序员把控制层东西交给Django自动完成了。 只需要编写非常少的代码完成很多的事情。所以,它比MVC框架考虑的问题要深一步,因为我们程序员大都在写控制层的程序。现在这个工作交给了框架,仅需写很少的调用代码,大大提高了工作效率。
一个更简单明了的图:

http://blog.51cto.com/12814931/2123622
Django框架全面讲解
https://www.cnblogs.com/LiCheng-/p/6920900.html
https://github.com/APSL/puput
如何在pycharm中安装django,实现django代码提示。
点“preferance-->在搜索框中输入package-->选择project interpreter-->点+号-->输入django,选择django”-->instll package.
三步搞定django网站。

一、Models
1.固定选项
如果要用固定的选项,可以用:
category = models.CharField(default="pxjg",verbose_name="培训机构",max_lenght=20, choices=(("pxjg","培训机构"),(“pxgr”,"培训个人"),("pxxx","培训学校")))
2、charField一定要设定max_lenght,textField不需要输入长度。
可以加unique=true
3、邮箱、URL
email = models.EmailField(max_length=50,verbose_name="邮箱")
url = models.URLField(max_length=200,verbose_name="访问地址")
download = models.FileField(upload_to="course/resource/%Y/%M",verbose_name="资源文件",max_length=100)

3、上传图片
看下面“upload_to=”的具体配置。

需要在项目根目录建立一个media文件夹,并在settings.py中添加如下代码:

在模板文件中用这样的方式调用。

要使Media_url生效,需要配置settings.py文件

用上面的调用,在前端还是显示不出来,还要加入以下代码:
from Mxonline.setting import MEDIA_ROOT
配置访问处理函数:

4、django的model中,HTMLField字段、DecimailField字段(DecimailField可以明确控制多少位,floatFiedl的位数多了去了)。
null=true 指的是数据库层面
blank = Ture 指的是前端表单提交是否可以为空

5、修改models时,只有更改到数据库,才需要migrate,仅仅影响到python层面的,比如default,blank,不影响数据库结构,不需要migrate。
下表列出了所有Django内置的字段类型,但不包括关系字段类型(字段名采用驼峰命名法,初学者请一定要注意):

6.一些常识
下面的代码,verbose_name 用于一进入后台,看到的各个管理项目显示的名称,比如可以管理文章,管理文章分类。
class Meta:
verbose_name = 'PPT目录管理'
verbose_name_plural = verbose_name
ordering = ("created_at",)
下面的代码,用于在后台显示条目的名称,比如如果是文章,在后台界面就显示文章的标题,不加的话,在后台会显示object之类的东西。
def __str__(self):
return self.name
如果后期要对数据库的字段进行修改,最好是删除原来的字段,然后再添加一个新的字段,防止数据库迁移的时候出现问题。
常用字段:
from django.db import models
from datetime import datetime
from django.contrib.auth.models import User
from django.utils.translation import gettext_lazy as _
# 候选人学历
DEGREE_TYPE = ((u'本科', u'本科'), (u'硕士', u'硕士'), (u'博士', u'博士'))
JobTypes = [
(0,"技术类"),
(1,"产品类"),
(2,"运营类"),
(3,"设计类"),
(4,"市场营销类")
]
Cities = [
(0,"北京"),
(1,"上海"),
(2,"深圳"),
(3,"杭州"),
(4,"广州")
]
class Job(models.Model):
# Translators: 职位实体的翻译
job_type = models.SmallIntegerField(blank=False, choices=JobTypes, verbose_name=_("职位类别"))
job_name = models.CharField(max_length=250, blank=False, verbose_name=_("职位名称"))
job_city = models.SmallIntegerField(choices=Cities, blank=False, verbose_name=_("工作地点"))
job_responsibility = models.TextField(max_length=1024, verbose_name=_("职位职责"))
job_requirement = models.TextField(max_length=1024, blank=False, verbose_name=_("职位要求"))
creator = models.ForeignKey(User, verbose_name=_("创建人"), null=True, on_delete=models.SET_NULL)
created_date = models.DateTimeField(verbose_name=_("创建日期"), auto_now_add=True)
modified_date = models.DateTimeField(verbose_name=_("修改日期"), auto_now=True)
class Meta:
verbose_name = _('职位')
verbose_name_plural = _('职位列表')
def __str__(self):
return self.job_name
class Resume(models.Model):
# Translators: 简历实体的翻译
username = models.CharField(max_length=135, verbose_name=_('姓名'))
applicant = models.ForeignKey(User, verbose_name=_("申请人"), null=True, on_delete=models.SET_NULL)
city = models.CharField(max_length=135, verbose_name=_('城市'))
phone = models.CharField(max_length=135, verbose_name=_('手机号码'))
email = models.EmailField(max_length=135, blank=True, verbose_name=_('邮箱'))
apply_position = models.CharField(max_length=135, blank=True, verbose_name=_('应聘职位'))
born_address = models.CharField(max_length=135, blank=True, verbose_name=_('生源地'))
gender = models.CharField(max_length=135, blank=True, verbose_name=_('性别'))
picture = models.ImageField(upload_to='images/', blank=True, verbose_name=_('个人照片'))
attachment = models.FileField(upload_to='file/', blank=True, verbose_name=_('简历附件'))
# 学校与学历信息
bachelor_school = models.CharField(max_length=135, blank=True, verbose_name=_('本科学校'))
master_school = models.CharField(max_length=135, blank=True, verbose_name=_('研究生学校'))
doctor_school = models.CharField(max_length=135, blank=True, verbose_name=u'博士生学校')
major = models.CharField(max_length=135, blank=True, verbose_name=_('专业'))
degree = models.CharField(max_length=135, choices=DEGREE_TYPE, blank=True, verbose_name=_('学历'))
created_date = models.DateTimeField(verbose_name="创建日期", default=datetime.now)
modified_date = models.DateTimeField(verbose_name="修改日期", auto_now=True)
# 候选人自我介绍,工作经历,项目经历
candidate_introduction = models.TextField(max_length=1024, blank=True, verbose_name=u'自我介绍')
work_experience = models.TextField(max_length=1024, blank=True, verbose_name=u'工作经历')
project_experience = models.TextField(max_length=1024, blank=True, verbose_name=u'项目经历')
class Meta:
verbose_name = _('简历')
verbose_name_plural = _('简历列表')
def __str__(self):
return self.username
小知识:
related_name用于外键的反向查询,也就是通过父表的一条记录,查询子表的多条记录。
比如查询一个县下面有多少个村,即使在一个表中,也是可以查询的。
二、URL.py
(一)URL的配置

提取URL中的变量
提取所有值,放到active_code当中。
![]()
(二)利用名称配置url

在模板中使用url的name进行配置,这样修改url的地址的时候,不用再修改模板中的配置。

三、views.py
测试用的:
from django.shortcuts import render,HttpResponse
# Create your views here.
def index(request):
return HttpResponse('hello')
模板
def index(request):
return render(request, 'ppt/index.html')
1.基于类的配置方法
(1)例子
首先要import进来
from django.views.generic.base import view

(2)相关说明:
A、关键变量。
queryset:用于提取数据,比如可以让提取的数据倒序排列。
context_object_name————在模板中的变量名。比如就是{% for question in questions %}中的questions。
template_name————-模板一般是一个html文件名
paginate_by————如果做分页这个参数说明每页有几个item项
model——————对应的模型(Model)
http_method_names———-请求类型 可以是get或者post
B、方法。
get_queryset——–或者需要展示的数据并且返回(必须要有返回)
get_context_data——–传递额外的数据到模板(html)。
(3)最简单的通用视图:
from django.views.generic import ListView
from .models import Article
class IndexView(ListView):
model = Article
尽管我们只写了一行model = Article, ListView实际上在背后做了很多事情:
提取了需要显示的对象列表或数据集queryset: Article.objects.all()
指定了用来显示对象列表的模板名称(template name): 默认app_name/model_name_list.html, 即blog/article_list.html.
指定了内容对象名称(context object name):默认值object_list
(4)加强版本
你或许已经注意到了2个问题:需要显示的文章对象列表并没有按发布时间逆序排列,内容对象名称object_list也不友好。或许你也不喜欢默认的模板名字,还希望通过这个视图给模板传递额外的内容(比如现在的时间)。
from django.views.generic import ListView
from .models import Article
from django.utils import timezone
class IndexView(ListView):
queryset = Article.objects.all().order_by("-pub_date")
template_name = 'blog/article_list.html'
context_object_name = 'latest_articles'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['now'] = timezone.now()
return context
如果上述的queryset还不能满足你的要求,比如你希望一个用户只看到自己发表的文章清单,你可以通过更具体的get_queryset方法来返回一个需要显示的对象列表。
from django.views.generic import ListView
from .models import Article
from django.utils import timezone
class IndexView(ListView):
template_name = 'blog/article_list.html'
context_object_name = 'latest_articles'
def get_queryset(self):
return Article.objects.filter(author=self.request.user).order_by('-pub_date')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['now'] = timezone.now()
return context
5.更多的view
更多的vies有DetailView、CreateView、UpdateView、FormView、DeleteView。
可参考:Django核心基础(3): View视图详解。一旦你使用通用视图,你就会爱上她(https://mp.weixin.qq.com/s?__biz=MjM5OTMyODA4Nw==&mid=2247483764&idx=1&sn=f0756dbb9887a05280e6464194477e1d&chksm=a73c614c904be85a8380a0d93155a5f70b9cdecf716f452ff9274a9ebeac1c194001beed7b23&scene=21#wechat_redirect)
2、首页显示多个分类的商品

3、用get查询,查不到会抛异常,用filter不会。
4.对数据的处理总结:
什么时候应该写在class里,什么时候写在views里。

四、模板
模板就4个东西:变量、标签、过滤器、注释。
五、注册后台

六、Debug
F6 单步调试、F8全速前进。
七、CSRF攻击
当我们在views.py中编写逻辑,获取表单中用户输入的用户名、密码等。

不过直接这样写会报错。因为django有一个跨站请求保护机制,只需要在模板文件中加入 {% csrf_token %}这一行代码即可。
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页</title>
</head>
<body>
<h1>用户输入:</h1>
<form action="/index/" method="post">
{% csrf_token %} <!--加入这行 -->
<input type="text" name="username" />
<input type="password" name="password" />
<input type="submit" value="提交" />
</form>
</body>
</html>
八、XSS攻击
尽量采用post而非get提交表单。
九、设置发送邮件

然后调用send_mail函数。