开始
1.创建项目:
django-admin startproject mysite
2.创建app
cd mysite
python manage.py startapp cmdb
3.运行
python manage.py runserver
目录结构与用途
mysite
- mysite 项目配置
- __init__
- settings 配置文件
- url url路由配置
- wsgi 遵循wsgi规范,上线uwsgi+nginx
- manage.py 管理Django程序
app:
- migrations 数据库表结构修改记录
- admin Django为我们的app程序自动创建的后台管理
- apps 对当前app的配置
- models 数据库orm,写指定的class,通过命令创建数据库结构
- tests 单元测试
- views app相关的所有业务,业务逻辑
配置
1.使用模板文件
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], ##新加
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
2.静态文件配置
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
# TEMPLATE_DIRS = (os.path.join(BASE_DIR, 'templates'),)
3.暂时停止POST跨站请求伪造
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
#'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
路由规则设定
- FBV
from cmdb import views # 在app中导入视图函数
# Django会默认添加/,此处url路由写的什么,html的form表单中action也必须相同
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^login', views.login),
url(r'^home', views.home),
]
- CBV
from mytest import views
urlpatterns = [
url(r‘^index/‘, views.Index.as_view()),
]
views视图函数:
- 形参:request client发送过来的各种信息
request.POST
request.GET
request.methed 为POST或者GET
- 值获取举例
# 单个值
request.POST.get("key",None)
request.GET.get("key",None)
# 多个值,返回一个list
request.GET.getlist("key",None)
request.POST.getlist("key",None)
视图函数返回
- 页面返回
- render 返回一个完整的html页面
- HttpResponse 返回字符串
- redirect 重定向,跳转动作不是在后台做的,不能写html模板路径
- 返回举例
return render(request, 'login.html', {"error_msg": error_msg}) 模板中通过key来获取,返回必须为一个字典,字典简直对适量不限制
return redirect("http://www.baidu.com") # 重定向
return redirect("/home") # 重定向
return HttpResponse("string")
模板渲染:
- 循环
{% for row in user_list %}
<tr>
<td>{{ row.username }}</td> 获得字典key对应的值
<td>{{ row.gender }}</td>
<td>{{ row.email }}</td>
</tr>
{% endfor %}
- 值获取:索引
eg:
return render(request, 'login.html', {"info": "Leon","user_list":[1,2,3,4,5],"user_dict":{"k1":"v1","k2":"v2"},})
列表或字典获取值:
{{ user_list.0 }}
{{ user_list.1 }}
{{ user_dict.k1 }}
{{ user_dict.k2 }}
- 条件判断
{% if info %}
{% if user_list.0 > 18 %}
<a>old</a>
{% else %}
<a>young</a>
{% endif %}
<a>用户为:info</a>
{% else %}
<a>用户为空</a>
{% endif %}
html数据提交
1. 单选框,name相同,value不同,才可以区分开,单个值用get可以获取
2. 复选框,name相同,value不同,多个用getlist获取,得到一个列表
3. select,select只有一个name,option中的value不同,多选在select中设定:multiple="multiple",后端依然使用getlist获取
4. 文件上传 :
前端:form表单中新增属性:enctype=“multipart/form-data”
后端:使用 obj = request.FILES,get(name) 来获取文件数据句柄
import os
file_path = os.path.join('upload',obj.name)
f = open(file_path,mode='wb')
for i in obj.chunks():
f.write(i)
f.close()
FBV和CBV
- urls中的区别在上面
- 视图函数写法:
from django.views import View
class Index(View): # 必须继承View
# 链接进来首先调用的是dispatch方法
def dispatch(self, request, *args, **kwargs): # dispatch使用了类似反射的方法,来区分get、post
# 调用父类中的dispatch
print(‘before‘) # 类似装饰器的功能
result = super(Home,self).dispatch(request, *args, **kwargs)
print(‘after‘) # 类似装饰器的功能
return result
def get(self, req):
print(‘method is :‘ + req.method)
return render(req, ‘index.html‘)
def post(self, req):
print(‘method is :‘ + req.method)
return render(req, ‘index.html‘)
路由系统url
1. 基本设定
url(r'^index/', views.index), # FBV
url(r'^home/', views.Home.as_view()), CBV
2. 正则匹配之无指定参数
url(r'^detail-(\d+).html', views.detail),
# 举例
url(r'^detail-(\d+)-(\d+).html', views.detail),
位置参数接收:前后对应
def func(request, nid, uid):
通用参数接收:都在args里
def func(request, *args):
def func(request, *args, **kwargs):
3. 有指定参数
url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail)
# 举例
url(r'^detail-(?P<nid>\d+)-(?P<uid>\d+).html', views.detail)
指定参数接收:
def func(request, nid, uid):
def func(request, nid, uid):
通用参数接收:
def funct(request, **kwargs):
kwargs = {'nid': 1, 'uid': 3}
4. name 可以根据此名称生成自己想要的URL
# urls设定
url(r'^asdfasdfasdf/', views.index, name='i1'),
url(r'^yug/(\d+)/(\d+)/', views.index, name='i2'),
url(r'^buy/(?P<pid>\d+)/(?P<nid>\d+)/', views.index, name='i3'),
# views函数设定
def func(request, *args, **kwargs):
from django.urls import reverse
url1 = reverse('i1') # asdfasdfasdf/
url2 = reverse('i2', args=(1,2,)) # yug/1/2/
url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # buy/1/9/
# 模板中设定
xxx.html
{% url "i1" %} # asdfasdfasdf/
{% url "i2" 1 2 %} # yug/1/2/
{% url "i3" pid=1 nid=9 %} # buy/1/9/
# 注:
# 当前的URL
request.path_info
5. 多级路由 app区分,多个app并行开发
- 项目主路由设定,分发到各个app
project/urls.py
from django.conf.urls import url,include
urlpatterns = [
url(r'^cmdb/', include("app01.urls")),
url(r'^monitor/', include("app02.urls")),
]
app01/urls.py
from django.conf.urls import url
from app01 import views
urlpatterns = [
url(r'^login/', views.login),
]
6.默认值
7.命名空间
django-orm
Django默认使用的为sqlite
,所以在使用mysql的时候需要对其进行相关设定
1.settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME':'dbname',
'USER': 'root',
'PASSWORD': 'xxx',
'HOST': '',
'PORT': '',
}
}
2. project项目下的__init__.py
由于Django默认使用MySQLdb,python3中无此模块,使用pymysql的话需要再次添加:
import pymysql
pymysql.install_as_MySQLdb()
3. 在settings中INSTALLED_APPS注册我们的app
4.app的models.py中创建表
from django.db import models
# Create your models here.
class UserInfo(models.Model):
# django会默认帮你创建一个自增id字段作为主键
username = models.CharField(max_length=32)
password = models.CharField(max_length=64)
email = models.EmailField()
5. makemigrations
python manage.py makemigrations
创建更改的文件
6.migrate
python manage.py migrate
将生成的py文件应用到数据库
7. 生成的表:
+----------------------------+
| Tables_in_cmdb |
+----------------------------+
| app_cmdb_userinfo |
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+----------------------------+
mysql> desc app_cmdb_userinfo;
+----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| username | varchar(32) | NO | | NULL | |
| password | varchar(64) | NO | | NULL | |
| email | varchar(254) | NO | | NULL | |
+----------+--------------+------+-----+---------+----------------+
Django ORM操作相关
1.添加数据
from app_cmdb import models
# 有几个字段,传几个参数就行了
models.UserInfo.objects.create(username="leon", password="123123", email='4641231@qq.com')
# 方法2
stu1 = user(username="leon", password="123123", email='4641231@qq.com')
stu1.save() # flush到数据库中
2.数据修改
# 单个数据的多个字段同时跟新
models.UserInfo.objects.get(username="leon", password="123123", email='4641231@qq.com').update(username="Leon",password="qweasdC")
# 跟新某个字段
user_obj = models.UserInfo.objects.get(username="leon", password="123123")
user_obj.username="Jack"
user_obj.save()
# 多条数据同时跟新
models.UserInfo.objects.all().update(username='Zhang')
3.数据删除
# 删除表中所有数据
models.UserInfo.objects.all().delete()
# 筛选单个删除
models.UserInfo.objects.get(username="leon").delete()
# 过滤多个删除
models.UserInfo.objects.filter(username="leon").delete()
4.数据查询,所有查询、过滤、排序、取值方法可以结合自己的使用场景来使用,以达到最佳的效果
# 查询所有记录
models.UserInfo.objects.all()
# 带字段名的所有记录,就是将所有记录以key-value的形式保存在字典中
models.UserInfo.objects.all().values()
>>><QuerySet [{'id': 1, 'username': 'leon', 'password': '123123', 'email': '4641231@qq.com'}, {'id': 2, 'username': 'leon', 'password': '1123123', 'email': '4641231@qq.com'}]>
# 查询单条记录,使用get查询单条数据,如果没有查到,会直接报错,结合try来使用
models.UserInfo.objects.get(name='Aaron')
# 查询多条中的第一条记录,多个过滤条件,需要在filter中用逗号分隔开
models.UserInfo.objects.filter(username='leon', password="123123").first()
# 模糊过滤,字段只要包含就可以
models.UserInfo.objects.filter(username__contains='leo').first()
# 模糊-不区分大小写
models.UserInfo.objects.filter(username__icontains='leo').first()
# 将字段内容排序后显示
models.UserInfo.objects.order_by('username')
# 查询记录的个数
models.UserInfo.objects.filter().conut()
# 筛选之大于小于,多个用逗号分开
models.UserInfo.objects.filter(id__gt=1) # 大于1
models.UserInfo.objects.filter(id__gte=1) # 大于等于1
models.UserInfo.objects.filter(id__lt=1) # 小于1
models.UserInfo.objects.filter(id__lte=1) # 小于等于1
models.UserInfo.objects.filter(id_gt=1,id__lte=10) # 大于1小于等于10
# in,not in
models.UserInfo.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据
models.UserInfo.objects.exclude(id__in=[11, 22, 33]) # not in
# 排序值逆序
models.UserInfo.objects.order_by('-username')
# 限制数据条数,因为返回的是一个QuerySet类型的列表,我们可以使用列表的分片来获取想要的数据内容,依然按照`顾首不顾尾`的原则
models.UserInfo.objects.filter(username="leon")[0] # 第一条数据
models.UserInfo.objects.filter(username="leon")[0:3] # 去前三条数据
5.数据字段类型
- 几种主要的类型之-数字类型
1. AutoField int类型(1 to 2147483647)的自增id列,须加参数 primary_key=True
2. BigAutoField bigint类型(1 to 9223372036854775807),同上
3. BigIntegerField
4. IntegerField
5. FloatField
6. SmallIntegerField
7. PositiveIntegerField
8. PositiveSmallIntegerField
- 字符串类型
1. CharField
2. EmailField (admin)
3. GenericIPAddressField (admin)
4. URLField (admin)
5. UUIDField
- 时间类型
1. DateField (Python:datetime.date)
2. DateTimeField (Python: datetime.datetime )
3. DecimalField (python : Decimal)
4. DurationField (python : timedelta)
5. TimeField (python : datetime.time)
- 二进制类型
1. BinaryField
- 布尔类型
1. BooleanField
- 文件类型
1. FileField
6.参数
- 基本
- null 是否可以为空
- default 默认值
- primary_key 主键
- db_column 舍子数据库中的列名
- db_index 建立普通索引
- unique 唯一索引
- unique_for_data 只对时间做索引
- unique_for_month 只对月份做索引
- unique_for_year 只对年份做索引
- auto_now 添加还是修改对象,时间为你添加或者修改的时间,需要使用obj.save()来跟新,而update不能跟新
- auto_now_add 创建时自动创建时间,跟新不动
- admin:
- choices 两个作用
user_type_choices = ( # 将这些字段放进内存,而避免数据库连表操作
(1,'root'),
(2,'root1'),
(3,'root1')
) 而且在django-admin中可以通过select直接选择
user_type_id = models.IntegerField(choices=user_type_choices,default=1)
- blank admin中是否可以为空
- verbose_name="用户名" 前端显示的别名
- editable 是否可以被编辑
- error_messages 输入错误提示消息自定义 error_messages={'required':u'邮箱不能为空'}????
- help_text help_text="user_name" 输入框下的用户提示信息
- validators Django的form自定义验证机制设置
7.外键的连表操作
- 表结构
class Host(models.Model):
nid = models.AutoField(primary_key=True)
hostname = models.CharField(max_length=32, db_index=True)
ip = models.GenericIPAddressField(db_index=True, protocol='ipv4')
port = models.IntegerField()
b = models.ForeignKey(to='Business', to_field='id')
class Business(models.Model):
caption = models.CharField(max_length=32)
code = models.CharField(max_length=32)
1.单表三种获取方式
# QuerySet内部为对象,模板获取的时候用"."来获取
v1 = models.Business.objects.all()
# QuerySet内部为key、value的字典,因为是字典,在模板中获取的时候用"."来获取,
v2 = models.Business.objects.all().values('id', 'caption') #只获取特定字段
# QuerySet内部为元组,因为是元组,在模板中获取的时候使用0,1,2的index来获取
v3 = models.Business.objects.all().values_list('id', 'caption')
- 举例:
# urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^business/$', views.business),
url(r'^host/$', views.Host.as_view()),
]
# views.py
def business(request):
v1 = models.Business.objects.all()
v2 = models.Business.objects.all().values('id', 'caption')
v3 = models.Business.objects.all().values_list('id', 'caption')
return render(request, 'business.html', {'v1': v1, 'v2': v2, 'v3': v3})
# business.html
<h1>(对象获取)</h1>
{% for foo in v1 %}
<li>{{ foo.id }}--{{ foo.caption }}--{{ foo.code }}</li>
{% endfor %}
<h1>(字典获取)</h1>
{% for foo in v2 %}
<li>{{ foo.id }}--{{ foo.caption }}</li>
{% endfor %}
<h1>(元祖获取)</h1>
{% for foo in v3 %}
<li>{{ foo.0 }}--{{ foo.1 }}</li>
{% endfor %}
2.连表三种获取方式
# QuerySet内部为对象,模板获取的时候用"."来获取
v1 = models.Host.objects.filter(nid__gt=0)
# QuerySet内部为key、value的字典,因为是字典,在模板中获取的时候用"."来获取,
v2 = models.Host.objects.all().values('nid', 'hostname', 'b_id', 'b__caption', 'b__code')
# QuerySet内部为元组,因为是元组,在模板中获取的时候使用0,1,2的index来获取
v2 = models.Host.objects.all().values_list('nid', 'hostname', 'b_id', 'b__caption', 'b__code')
- 举例
# urls.py
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^business/$', views.business),
url(r'^host/$', views.Host.as_view()),
]
# views.py
class Host(View):
def get(self, request):
v1 = models.Host.objects.filter(nid__gt=0)
v2 = models.Host.objects.all().values('nid', 'hostname', 'b_id', 'b__caption', 'b__code')
v3 = models.Host.objects.all().values_list('nid', 'hostname', 'b_id', 'b__caption', 'b__code')
return render(request, 'host.html', {'v1': v1, 'v2': v2, 'v3': v3})
def post(self, request):
pass
# host.html
<h1>对象</h1>
{% for row in v1 %}
<tr host_id="{{ row.nid }}" b_id="{{ row.b_id }}">
<td>{{ row.hostname }}</td>
<td>{{ row.ip }}</td>
<td>{{ row.port }}</td>
<td>{{ row.b.caption }}</td>
</tr>
{% endfor %}
<h1>字典</h1>
{% for row in v2 %}
<tr host_id="{{ row.nid }}" b_id="{{ row.b_id }}">
<td>{{ row.hostname }}</td>
<td>{{ row.b__caption }}</td>
</tr>
{% endfor %}
<h1>元组</h1>
{% for row in v3 %}
<tr host_id="{{ row.0 }}" b_id="{{ row.2 }}">
<td>{{ row.1 }}</td>
<td>{{ row.3 }}</td>
</tr>
{% endfor %}