目录
一、创建django项目
二、创建app
三、定义路由规则
四、定义视图函数
五、模板语言
六、数据库操作
七、Ajax
===================================================
一、创建django项目
djano-admin startprojrct project_name_diy
创建完Django项目后,自动建立以下目录
Demo
--Demo
--init
--settings 配置文件
--url url对应关系
--wsig 遵循WSGI规范UWGI+nginx
--manage.py管理Gjango程序
可以通过以下命令启动服务
python manage.py runserver host_diy:port_diy
二、创建并注册app
1.创建APP
创建一个app,自动生成同名的目录,在PyCharm左下角选择Terminal输入以下命令
python manage.py startapp app_name_diy
创建后的app有以下文件夹,各目录功能解释:
--app_name
--migrations 数据修改表结构的记录
--admin Django提供的后台管理
--app 配置当前的app
--models orm,写指定的类,通过命令创建数据库结构
--tset 单元测试
--views 所有的业务代码
2.注册app
在settings.py中,注册app(即添加app的名字)
在写好了models类之后必须在settings下做配置,否则在多个app时,Django会因为不知道找哪个app下的models生成表,因此会报错,具体的配置为
INSTALLED_APPS=[... , 'app_name']
三、配置与新建的文件夹
1.配置静态文件:
在工程目录下添加static目录,并且在settings.py中,添加以下配置信息:(注意是列表,后面的逗号)
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static'),
]
2.配置模板路径:
在工程目录下添加templates目录,在settings.py下,找到以下TEMPLATES,在其中的 'DIRS'添加
os.path.join(BASE_DIR,"templates"):
3.数据库
Dango默认是那个mysqldb模块,但是python3.x没有这个模块,我们使用pymysql模块,在project同名文件下的\__init__.py文件中添加以下语句即可
import pymysql
pymysql.install_as_MySQLdb()
Django连接数据库时默认使用的是Sqlite3,如果要使用其他的数据库,则需要在settings中修改DATABASE
使用mysql的配置【需要注意:Django不能创建数据库,所以下面的NAME必须时已经存在的数据库的名称,即需要先创建数据库】:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'mydatabase', #数据库的名称
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword', #数据库密码
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
#其他的ENGINE:
```
'django.db.backends.postgresql'
'django.db.backends.mysql'
'django.db.backends.sqlite3'
'django.db.backends.oracle'
```
4.注释
(后期可以不注释)
在settings.py下,找到以下MIDDLEWARE,注释以下内容:
#'django.middleware.csrf.CsrfViewMiddleware',
5.一些常用命令
python manage.py createsuperuser # 创建超级用户
python manage.py createcachetable [table_name] # 创建缓存表
三、定义路由规则
1.普通的路由
path(r'',views.index) #匹配空字符串
path(r'detail/',views.detail1)
2.正则表达式的路由
re_path(r'detail-(\d+).html/',views.detail2)
3.含参数的路由,带参数(?p<>)
re_path(r'detail-(?P<nid>\d+)-(?P<uid>\d).html/',views.detail3)
def detail(request,*akgs,**kwargs):
...
上述带参数的方式2和3,再views.py中的函数会由不同类型的参数接收
方式2的参数传给args,方式3的参数传给kwargs
4.为路由设置名称
name是对路由关系进行命名,以后可以根据name生成自己想要的URL
url.py:
re_path(r'index/(\d+)/',views.index,name="myindex")
re_path(r'index/',views.index,name="n1")
re_path(r'index/(\d+)/',views.index,name="n2")
re_path(r'index/(?P<nid>\d+)-(?P<uid>\d)/',views.index,name="n3")
views.py:
from django.urls import reverse
def index(request,*args,**kwargs)
url1=reverse("n1")
url2=reverse("n2",args=(11,))
url3=reverse("n3",kwargs={"nid":111,"uid":222})
xx.html:
action="{% url "n1" %}"
action="{% url "n2" 11 %}"
action="{% url "n3" nid=111 uid=222%}"
四、定义视图函数
project->app->views.py定义一个处理函数
from django.shortcuts import HttpResponse
from django.shortcuts import render , redirect
def function(request):
request.method #得到提交方式:POST,GET
request.GET.get("",None) #获得请求的数据
request.POST.get("",None) #获得请求的数据
request.POST.getlist("") #获得请求多选的数据
request.FILES.get("") #获取文件
return HttpResponse(string)
return render(request,path_html) #在已经配置好模板路径时,path_html的上一层路径是project下的templates。
return redirect(url) #以GET的方式访问
上传文件
import os
def function(request):
obj=request.FILES.get("xx")
path=os.path.join(file_path,file_name)
=open(path,mode="wb")
for i in f:
f.write()
f.close
五、模板语言
1.for循环
对列表的循环
{%for row in list%}
<tr>
<td>{{row.username}}</td>
<td>{{row.email}}</td>
<td>{{row.gender}}</td>
</tr>
{% endfor %}
对字典的循环
<!--取键和值-->
{%for k,v in dict%}
<tr>
<li>{{k}}--{{v}}</li>
</tr>
{% endfor %}
<!--取键-->
{%for k in dict.keys%}
<tr>
<li>{{k}}</li>
</tr>
{% endfor %}
<!--取值-->
{%for v in dict.values%}
<tr>
<li>{{v}}</li>
</tr>
{% endfor %}
2. if
可以多层嵌套
{%if 条件%}
{%else%}
{%endif%}
3.列表和字典的引用
引用其中的单个值
<!--引用列表-->
list.0
list.1
list.2
<!--引用字典-->
dir.key1
dir.key2
dir.key3
4.序号
{%for line in list%}
<td>{{forloop.first}}</td> <!--返回布尔值,判断是否是第一个-->
<td>{{forloop.last}}</td> <!--返回布尔值,判断是否是最后一个-->
<td>{{forloop.counter}}</td> <!--从1开始-->
<td>{{forloop.counter0}}</td> <!--从0开始-->
<td>{{forloop.recounter}}</td> <!--倒数到 1-->
<td>{{forloop.recounter0}}</td> <!--倒数到0 -->
<td>{{forloop.parentloop}}</td> <!--多层循环中,上一层循环到第几次-->
{%endfor%}
5.
以form表单提交数据时,页面会刷新。
六、数据库操作
ORM
根据类创建数据库
1.app下的models.py
class class_name(models.Model): #必须继承这个类
colunm_name1=models.AutoField(primary_key=True) #如果没有创建自增列,则自动创建id列,且是主键。这里自己创建主键,必须有这个参数。
colunm_name2=models.CharField(max_length=xx)
其他字段的补充:
看起来有这么多的类型,但是其实数据类型没这么多,大多数本质上是字符串类型。那为什么要设计这么多呢?不能帮助检验数据的格式,但是能在Django admin下作限制 。
AutoField(Field) - 自增列,int型,必填参数 primary_key=True
BigAutoField(AutoField) - 自增列,big int型,必填参数 primary_key=True
注:(以上两个)当model中如果没有自增列,则自动会创建一个列名为id的列
FloatField(Field) - 浮点型
DecimalField(Field) - 十进制小数
- 参数: max_digits,小数总长度
decimal_places,小数位长度
CharField(Field) - 字符类型 - 必须提供max_length参数,max_length表示字符长度
TextField(Field) - 文本类型
EmailField(CharField): - 字符串类型,Django Admin以及ModelForm中提供验证机制,验证是否是邮箱格式
DateField(DateTimeCheckMixin, Field) - 日期格式 YYYY-MM-DD
TimeField(DateTimeCheckMixin, Field) - 时间格式 HH:MM[:ss[.uuuuuu]]
DateTimeField(DateField) - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
BinaryField(Field) - 二进制类型
DurationField(Field) - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
IntegerField(Field) -(-2147483648 ~ 2147483647 )
PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) -(0 ~ 2147483647 )
SmallIntegerField(IntegerField): -(32768 ~ 32767 )
PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField) - (0 ~ 32767 )
BigIntegerField(IntegerField): -(-9223372036854775808 ~ 9223372036854775807 )
BooleanField(Field) - 布尔值类型
NullBooleanField(Field): - 可以为空的布尔值
IPAddressField(Field) - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制(一般不用这个,而使用下面的GenericIPAddressField)
GenericIPAddressField(Field) - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
- 参数: protocol用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6" unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启此功能,需要protocol="both"
URLField(CharField) - 字符串类型,Django Admin以及ModelForm中提供验证 URL
----------------------------------------------------------------------------------------------
SlugField(CharField) - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
CommaSeparatedIntegerField(CharField) - 字符串类型,格式必须为逗号分割的数字
UUIDField(Field) - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
FilePathField(Field) - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
- 参数: path, 文件夹路径 match=None, 正则匹配
recursive=False, 递归下面的文件夹
allow_files=True, 允许文件 allow_folders=False, 允许文件夹
FileField(Field) - 字符串,路径保存在数据库,文件上传到指定目录
- 参数: upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
ImageField(FileField) - 字符串,路径保存在数据库,文件上传到指定目录
- 参数: upload_to = "" 上传文件的保存路径
storage = None 存储组件,默认django.core.files.storage.FileSystemStorage
width_field=None, 上传图片的高度保存的数据库字段名(字符串)
height_field=None 上传图片的宽度保存的数据库字段名(字符串)
补充参数说明
null 数据库中字段是否可以为空
auto_now_add 创建数据时,自动生成时间
auto_now 更新数据时,自动更新为最新修改时间
-obj=User.objects.filter(条件).update(xx) 这种更新方法,auto_now_add不起效果
-obj=User.objects.filter(条件)。first() 这种方法才有效果,会更新修改时间
obj.column_name=new_value
obj.save()
db_tablespace
primary_key 主键(bool) 数据库中字段是否为主键
default 默认值(any) 数据库中字段的默认值
db_column 列名(string) 数据库中字段的列名
db_index 索引(bool) 数据库中字段是否可以建立索引
unique 唯一索引(bool) 数据库中字段是否可以建立唯一索引
unique_for_date 数据库中字段【日期】部分是否可以建立唯一索引
unique_for_month 数据库中字段【月】部分是否可以建立唯一索引
unique_for_year 数据库中字段【年】部分是否可以建立唯一索引
verbose_name (string) django dmin中显示的字段名称
blank (bool) django dmin中是否允许用户输入为空
editable (bool) django dmin中是否可以编辑
help_text (string) django dmin中该字段的提示信息
choices (tuple,list) django dmin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
例如:user_type((1,'学生'),(2,'老师'),(3,'管理员'),)
user_type_id=models.IntegerField(choices=user_type,default=1)
error_messages (dict) django dmin自定义错误信息,从而定制想要显示的错误信息;
字典键:null, blank, invalid, invalid_choice, unique, and unique_for_date
如:{'null': "xx不能为空.", 'invalid': 'xx格式错误'}
validators (list) 自定义错误验证,从而定制想要的验证规则
外键:通过fk,B可以跨表查询A中的数据,A也可以通过B_set跨表查询A中的数据
class A:
...
class B
...
fk=ForeignKey(A)
3.创建数据库、修改数据库的表结构
在Terminal下执行以下命令:
python manage.py makemigrations #->在migrations中生成临时文件
python manage.py migrate #->根据临时文件进行操作
七、Ajax
1.Ajax
$.ajax({
url:" ", //提交到哪里
type:" ", //以什么方式提交,POST、GET等
data:{ key1:value1, //提交的数据
key2:value2,
...},
success:function(data)(){ //匿名函数,发送请求时不执行,等待服务端返回数据时自动触发执行,返回的数据就是参数data
}
})
$.get(url="",data={...},sucess=...)
$.post(url="",data={...},sucess=...)
想要做到使用ajax提交form表单:
type=submit会导致页面刷新,如果不需要刷新就就可以把type=button
<form method="post" id="register_form">
{%csrf_token%}
<input type="text" name="aa">
<input type="button" value="注册" onclick="register()">
</form>
<script>
function register() {
// 把数据更新到comment_text
$.ajax({
url: "{% url 'register'%}",
type: "POST",
data: $("#register_form").serialize(),
cache: false,
dataType: "json",//预期服务器返回的数据类型
success:function(data) {
if(data["create"]){
var a="<a href='{% url 'login' %}'>注册成功,现在去登录</a>";
$("#register_form").after(a);
}
else{
var span="<span class=''>"+ data["msg"] +"</span>";
console.log(span);
$("#register_form").after(span);
}
},
error: function() {
}
});
return false;
}
</script>
2.序列化与反序列化:
前端:
$.ajax({
url:"",
...
success:function(data){
var obj=JSON.parse(data); #->把字符串变成对象,使用"."来引用
var str=JSON.stringfy(obj) #->八对象妆化成字符串
}
后台:
使用ajax,在views.py视图函数中推荐使用HttpResponse,可以使用render,但是不可以使用redirect。
import json
ret={'status':True,"error":None,"data":None}
return HttpResponse(json.dumps(ret)) #把字典变成字符串,然后传给前端