Django开发
自动管理工具
创建App
python manage.py startapp XXX
配置自动管理工具,在settings.py 中
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
)
激活自动管理工具,在urls.py中
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
]
创建管理工具的超级用户,在terminal中
python manage.py createsuperuser
Username(leave blank to use 'administrator'):
Email address:
Password:
Password(again):
Superuser created successfully
访问 127.0.0.1:8000/admin
创建模型或同步模型变更
python manage.py makemigrations [XXModel] #通知Django创建/变更
python manage.py migrate [XXModel] #创建/更新表结构
注册数据模型到管理工具,XXModel/admin.py中
from django.contrib import admin
from XXModel.models import XXModel
admin.site.register(XXModel)
admin.site.register([XXModel, Contact, Tag]) #注册复杂模型
class ContactAdmin(admin.ModelAdmin): #自定义表单
fields = ('name', 'email')
class XXModelAdmin(admin.ModelAdmin): #自定义表单-分栏
list_display = ('name','age', 'email') # list显示
search_fields = ('name',) # 搜索栏
fieldsets = (
['Main',{
'fields':('name','email'),
}],
['Advance',{
'classes': ('collapse',), # CSS
'fields': ('age',),
}]
)
class TagInline(admin.TabularInline): #自定义表单-内联
model = Tag
```
## 访问 Django /admin/ 提示 AttributeError at /admin/
>AttributeError at /admin/
'WSGIRequest' object has no attribute 'user'
Request Method: GET
Request URL: http://localhost:8000/admin/
Django Version: 1.8.2
Exception Type: AttributeError
Exception Value:
'WSGIRequest' object has no attribute 'user'
项目settings中的`MIDDLEWARE`改为`MIDDLEWARE_CLASSES`,1.10之后采用新命名`MIDDLEWARE`,部署时使用1.10之前的就需要用`MIDDLEWARE_CLASSES`做兼容。
且中间件要按顺序排列,因其是从上到下的顺序一个个执行 process_request 函数。
保持一下顺序:
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
# 数据库相关
没有安装任何的数据库软件,django 就帮我们迁移了数据库,这是因为我们使用了 Python 内置的 SQLite3 数据库。
## Django自带的sqlite3操作
更新模型操作
方法一:
User.objects.filter(id=1).update(username='nick',is_active=True)
方法二:
_t = User.objects.get(id=1)
_t.username='nick'
_t.is_active=True
_t.save()
方法一:
data = {'username':'nick','is_active':'0'}
User.objects.filter(id=1).update(* * data)
方法二:
data = {'username':'nick','is_active':'0'}
_t = User.objects.get(id=1)
_t.__dict__.update(**data)
_t.save()
方法三:
_t = User.objects.get(id=1)
_t.role=Role.objects.get(id=3)
_t.save()
自动填充时间字段:
class User(models.Model):
create_time = models.DateTimeField(auto_now_add=True, verbose_name=’创建时间’)
update_time = models.DateTimeField(auto_now=True, verbose_name=’更新时间’)
username = models.CharField(max_length=255, unique=True, verbose_name=’用户名’)
is_active = models.BooleanField(default=False, verbose_name=’激活状态’)
auto_now选项必须配合更新中的方法二使用才有效。
[参考](https://juejin.im/post/5b588b656fb9a04fba6e8681)
小方法:
model_to_dict(model) : model_to_dict(User.objects.get(id=1))
list(queryset) : list(User.objects.filter(id=1))
queryset : all、filter、order_by
model : get
## 根据数据库生成 models
$ python manage.py inspectdb
指定app的 models
$ python manage.py inspectdb > app/models.py
对于自己需进行 CRUD 的 models,在 Meta 中设置 managed = True
数据库已存在,迁移时需要使用 --fake-initial 参数
$ python manage.py makemigrations
$ python manage.py migrate --fake-initial
注册 models
blog/admin.py
from django.contrib import admin
from .models import MyModel
admin.site.register(MyModel)
不是 —fake 而需要真实改动数据库结构
python manage.py migrate --fake core 0003
python manage.py migrate core
最后对Django 全局/app migrate
$ python manage.py migrate your_app
观察 django 通过检测应用中 migrations\ 目录下的文件,把这些操作翻译成数据库操作语言,以下为翻译表创建语句例子,这有助于理解 django ORM 的工作机制
pipenv run python manage.py sqlmigrate blog 0001
## mysql
mysql创建假数据
>INSERT INTO users ( id, email, passwd, admin, name, image, created_at ) VALUES ( "2", "bob@efun.com", "234", 0, "bob", "https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=3987907653,720009510&fm=26&gp=0.jpg", NOW());
>UPDATE users SET image="https://ss0.bdstatic.com/70cFuHSh_Q1YnxGkpoWK1HF6hhy/it/u=508387608,2848974022&fm=26&gp=0.jpg" WHERE id="1";
## Django 中的 CharField vs TextField
CharField()应该用于较小的字符串,而TextField()应该用于较大的字符串。
当需要限制最大长度时,使用CharField,否则使用TextField。
## Django 中的 null=True vs blank=True
null=True 表示可设置 NULL (versus NOT NULL) 在你数据库的属性里。
blank=True 表示表单中是否必需此属性,True时表示可以为空。
## 解决 python No migrations to apply 无法生成表
删除该app名字下的migrations文件
删除django_migrations表
$ sqlite3 db.sqlite
.table
drop django_migrations;
.quit
重新迁移
$ python manage.py makemigrations
$ python manage.py migrate
# 模板相关
## 导入模块
在模板文件的开头写下如 `{% load static %}`,或 `{% load your_tag_name %}`,就可以在模板中使用文件里的函数(static 是我们常用的,用于获取静态文件完整URL的部分)
函数需要被模板过滤器包装
from django import template
register = template.Library()
@register.filter
def json_str(value):
return value
使用方法如下,作用就是将 vs 通过管道输入 json_str 方法中过滤,得到的值赋给button的value,而经过 static 处理的值就是指向静态文件绝对路径的地址
{% load your_tag_name %}
···
最后还需在 settings.py 上设置 `TEMPLATES`
TEMPLATES = [
{
…
‘OPTIONS’: {
‘context_processors’: [
‘django.template.context_processors.debug’,
…
],
‘libraries’: {
‘your_tag_name’: ‘your_tag_file_module_path’,
}
},
},
]
一般新建一个 package 文件装载所有相关的 template 的 tag library,便于管理。
## CSRF
在模板的 form 标签内容中添加以下便签通配
{% csrf_token %}
可自动生成带 csrf token 的隐藏 input 标签
若不用 form 的 submit,可在参数中额外添加以下字段通过服务端的 csrf 验证
params.csrfmiddlewaretoken: $(“input[name=’csrfmiddlewaretoken’]”).attr(“value”)
否则用 postman 进行 post 请求时会收到 Forbidden (CSRF cookie not set.) 403
## 静态文件的访问
每个应用中也可以新建一个 static 文件夹,里面再分门别类地创建文件夹,比如 css、js、scripts、images、mp3 等等,但文件名最好是保证唯一的,或可用应用名作前缀命名文件夹,又或者可在 static 文件夹下先建一个与应用名一致的文件夹,再在它里面创建分类的文件夹或文件,从而避免静态资源被收集时覆盖根目录下的文件。
最终,所有静态文件,包括根工程 static 里的和各个应用 static 里的所有静态资源都会被汇总起来,注意,只有通过命令行的方式启动时才会有自动汇总的效果,像使用 uwsgi 的方式启动则需要自行用 collectstatic 指令汇总。这样,若要在模板中使用这些静态资源,就可以通过直接请求像 /static/xx/yy.png 这样的链接,xx 表示刚才在根工程 static 和各个应用 static 下创建的路径。
运行 collectstatic 有个前提,是需要在工程的 `settings.py` 里做好以下设置
映射到 django.contrib.staticfiles app,自动搜索静态文件
STATIC_URL = ‘/static/‘
开发阶段放置项目自己的静态文件,和生产阶段需收集的文件
STATICFILES_DIRS = (
os.path.join(BASE_DIR, ‘staticfiles’),
)
执行collectstatic命令后会将项目中的静态文件收集到该目录下面来(所以不应该在该目录下面放置自己的一些静态文件,因为会覆盖掉)
STATIC_ROOT = os.path.join(BASE_DIR, ‘static’)
小结来说,在开发阶段,Django 把 /static 映射到 django.contrib.staticfiles 这个 App。staticfiles 自动地从`STATICFILES_DIRS`、`STATIC_ROOT`以及`各个App的static`子目录里面搜索静态文件。一旦布署到开发环境上,settings.py不需要重新编写,只要在 Nginx 的配置文件里面写好映射,/static 将会被 Nginx 处理。django.contrib.staticfiles虽然仍然存在,但因为不会接收到以 /static/ 开始的路径,所以将不会产生作用,不必担心 Django 使用处理速度变慢。另外,当settings.DEBUG is False的时候,staticfiles将自动关闭。
### 排查静态文件无法访问的问题
1.settings.py 里的 INSTALLED_APPS 是否包含 `django.contrib.staticfiles`
2.settings.py 里是否有以下设置(其实默认会带有而无需显式设置)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
3.非 DEBUG 下,使用 `--insecure` 参数启动(但不安全)
python manage.py runserver --insecure
或在 urls.py 中的 urlpatterns 添加项,但响应速度也会变慢
url(r'^static/(?P<path>.*)$', static.serve, {'document_root': settings.STATIC_ROOT }, name='static'
DEBUG = True 则应该可以正常访问。
4.设置上 STATIC_ROOT 时,需要运行收集根和应用下的静态文件指令
python manage.py collectstatic
5.STATICFILES_DIRS 主要用于设置其它目录下的静态文件(非根或应用下的 static 目录,作为在执行上面第4点的指令收集时去寻找的路径),没有设 STATIC_ROOT 时需要将根的 static 在此设置
6.模板中使用 {% load static %} 和 href="{% static 'css/bootstrap.css' %}" 访问,js 上可用 'static/css/bootstrap.css' 请求
# 接口相关
## 接收 ajax 的数组参数
js:
var id_list = [1, 2, 3]
var params = {
id_list: id_list,
};
$.ajax({
…
data: params,
…
});
python:
method = request.POST
id_list = method.get(“id_list[]”)
python 中接收的字段名需添加后缀 `[]`,但这只会返回数组中的最后一个元素,正确使用如下
method = request.POST
id_list = method.getlist(“id_list[]”)
# 参考
* [Django 中STATIC_ROOT 与STATICFILES_DIRS的区别-阳明的博客|Kubernetes|Istio|Prometheus|Python|Golang|云原生](https://www.qikqiak.com/post/django-staticroot-staticfilesdirs-function/)
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 mingfungliu@gmail.com
文章标题:Django开发
文章字数:2.3k
本文作者:Mingfung
发布时间:2019-05-15, 12:33:00
最后更新:2020-12-07, 09:23:04
原始链接:http://blog.ifungfay.com/uncategorized/Django开发/版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。