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.模板中使用 &#123;% load static %&#125; 和 href="&#123;% static 'css/bootstrap.css' %&#125;" 访问,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" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏

宝贝回家