Django总结

Posted by BenderFly on May 16, 2019

1.工程下建立APP

django-admin startproject myweb  #建立项目
cd myweb
django-admin startapp myapp #建立项目下属APP

编辑 models.py 文件,改变模型。

运行 python manage.py makemigrations 为模型的改变生成迁移文件。
运行 python manage.py migrate 来应用数据库迁移。   

2.APP下的models.py文件中加入表结构

(django中之所以把表结构在自身文件中定义,是为了在其他文件中可直接引用表结构进行数据库操作,不用频繁刷新数据表获取表结构)

from django.db import models

# Create your models here.

class book_info(models.Model):
    fromuser = models.CharField(max_length=30, default='WYS')
    fromsite = models.CharField(max_length=50)
    bookname = models.CharField(max_length=50)
    #updatetime = models.DateTimeField()
    #lastchapter = models.CharField(max_length=100)

class site_info(models.Model):
    sitename = models.CharField(max_length=50)
    bookname = models.CharField(max_length=50)
    url = models.CharField(max_length=200)
    updatetime = models.DateTimeField()
    lastchapter = models.CharField(max_length=100)
	

django中自定义表名及字段名称 在meta 类中指定表名,在字段中通过db_column指定列名 如下所示

class Record(models.Model):
    content=models.CharField(max_length=32,db_column='record_content')
    class Meta:
        db_table="Record"

3.在myweb/myweb/settings.py中加入创建的APP和MYSQL连接信息

INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'myapp',
)

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test',
        'USER': 'test',
        'PASSWORD': 'test',
        'HOST': 'localhost',
        'PORT': '3306',
    }
}

4.将models.py中的数据库表结构同步到MYSQL中

python manage.py migrate #创建表结构
python manage.py makemigrations myapp #告诉django,myapp中的表结构有更新
python manage.py migrate myapp  #执行myapp中的表结构到mysql中
数据库中的表名为myapp_book_info,myapp_site_info,但django代码中调用时的表名为models.py中定义的表名book_info,site_info

5.数据表操作-增

from myapp.models import book_info
test1 = book_info(fromuser='testuser',fromsite='testsite',bookname='testbookname')
test1.save()
 

book_info.objects.create(fromuser='testuser',fromsite='testsite',bookname='testbookname')

6.数据库操作-删

test1 = book_info.objects.get(bookname='testbookname')
test1.delete()
book_info.objects.filter(bookname='testbookname').delete()
book_info.objects.all().delete()

7.数据库操作-改

test1 = book_info.objects.get(bookname='testbookname')
test1.bookname = 'book1'
test1.fromuser = 'user1'
test1.save
book_info.objects.filter(bookname='testbookname').update(fromuser='user1')
book_info.objects.all().update(fromuser='user1')

8.数据库操作-查

list = book_info.objects.all()
for i in list:
    print(i.book_name)
list = book_info.objects.filter(bookname='testbookname', fromuser='testuser')  #类似于SQL中的WHERE
list = book_info.objects.filter( fromuser__contains='testuser')  #注意中间是双下划线,类似于SQL中的where fromuser like "%testuser%" 
#此外还有icontains(大小写无关的like),startswith和endswith, 还有range(SQL BETWEEN查询)
list = book_info.objects.get(bookname='testbookname')  #返回单条记录,不需要for直接list.bookname使用
list = book_info.objects.filter().exclude().filter() #可无限嵌套
book_info.object.all()[:5]  #前5条记录
book_info.object.order_by(bookname)[2:5]  #排序后的第3、4、5条记录
book_info.object.order_by(bookname)[0]  #排序后的第1条记录
book_info.object.order_by(bookname)[0:1].get() #排序后的第1条记录
book_info.object.all()[:10:2]  #从第1条记录到第11条记录步长为2的数据集

9.常用查询条件

__exact 精确等于 like ‘aaa’ 
__iexact 精确等于 忽略大小写 ilike ‘aaa’ 
__contains 包含 like ‘%aaa%’ 
__icontains 包含 忽略大小写 ilike ‘%aaa%’,但是对于sqlite来说,contains的作用效果等同于icontains。 
__gt 大于 
__gte 大于等于 
__lt 小于 
__lte 小于等于 
__in 存在于一个list范围内 
__startswith 以…开头 
__istartswith 以…开头 忽略大小写 
__endswith 以…结尾 
__iendswith 以…结尾,忽略大小写 
__range 在…范围内 
__year 日期字段的年份 
__month 日期字段的月份 
__day 日期字段的日 
__isnull=True/False 
__isnull=True 与 __exact=None的区别

10.查询指定字段values和values_list

values_list(*fields, flat=False) 与values() 类似,只是在迭代时返回的是元组而不是字典。每个元组包含传递给values_list() 调用的字段的值 —— 所以第一个元素为第一个字段,以此类推。例如: 如果只传递一个字段,你还可以传递flat 参数。如果为True,它表示返回的结果为单个值而不是元组。一个例子会让它们的区别更加清晰:

>>> Entry.objects.values_list('id').order_by('id')
[(1,), (2,), (3,), ...]

>>> Entry.objects.values_list('id', flat=True).order_by('id')
[1, 2, 3, ...]

values(*fields) 返回一个ValuesQuerySet —— QuerySet 的一个子类,迭代时返回字典而不是模型实例对象。

>>> Blog.objects.values()
[{'id': 1, 'name': 'Beatles Blog', 'tagline': 'All the latest Beatles news.'}],
>>> Blog.objects.values('id', 'name')
[{'id': 1, 'name': 'Beatles Blog'}]

values方法可以获取number字段的字典列表。 values_list可以获取number的元组列表。 values_list方法加个参数flat=True可以获取number的值列表。

11.配置文件

配置中文,时区

LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'

12. admin配置

注册model

@admin.register(About)
class AboutAdmin(admin.ModelAdmin):
    list_display = ['id', 'content']

#添加到一个app下就可以
admin.site.site_header = '深圳气象局高性能网后台管理-平台简介'
admin.site.site_title = '深圳气象局高性能-平台简介'

13.apps.py

from django.apps import AppConfig


class HomeConfig(AppConfig):
    name = 'home'
    verbose_name = " App中文名称"

#设置verbose_name字段,来指定app在后台显示的名称,仅仅增加verbose_name之后,仍然没有效果。在导入app时,django会检查每个在INSTALLED_APPS中的app的default_app_config变量,如果没有设置,django会使用基类AppConfig,因此我们只需要在init.py中指定default_app_config即可,如下:

# blog/__init__.py ,blog为app名称
default_app_config = 'blog.apps.BlogConfig'

通过以上两步,即可实现自定义app在admin中的显示名称。

14.models.py

#verbose_name设置字段名称
content = models.TextField(help_text="资源环境",verbose_name="资源环境")
#返回类型
    def __str__(self):
        return str(self.id)

#verbose_name_plural设置表名称(前面加空格排序,空格越多排名越前)
    class Meta:
        verbose_name_plural = '  平台概况'

15. 静态文件

template/base.html

{ % load staticfiles % }
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{ % block title % }标题{ % endblock % }</title>
    <link rel="shortcut icon" href="{ % static 'images/favicon.ico'% }" type="image/x-icon">
    <link rel="stylesheet" href="{ % static 'css/base_cn.css' % }" media="screen,print"/>

</head>
<body>
<a href="{ % url 'home:solution_detail' 1% }" title='电子车间 净化工程' class="" >● 电子车间 净化工程</a>
</body>
</html>

修改配置文件settings.py

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [
                os.path.join(BASE_DIR, 'templates'),  # 使得能够自动在各个templates目录寻找
        ],
		...
		



STATIC_URL = '/static/'  # STATIC_URL是指从浏览器访问时的地址前缀
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), "static_cdn")  #静态文件位置

MEDIA_URL = '/media/'    #url访问路径
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "media_cdn")     #静态文件位置

STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "commstatic"), #额外的静态文件位置(可选)STATICFILES_DIRS告诉django,首先到STATICFILES_DIRS里面寻找静态文件,其次再到各个app的static文件夹里面找
]

collectstatic收集静态文件

python manage.py collectstatic

继承基础模板 app/template/home/index.html

{ % extends 'base.html' % }
{ % load staticfiles % }
{ % block content % }
...
{ % end block content% }

16. url.py

from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('ckeditor', include('ckeditor_uploader.urls')),
	path('hpc/', include('hpc.urls')),
    path('resource/', include('resource.urls')),
    path('guide/', include('guide.urls')),
]

17.Ckeditor

settings.py


INSTALLED_APPS = [
...
    'ckeditor',
    'ckeditor_uploader',
...
]

# media
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')


# 配置ckeditor
CKEDITOR_UPLOAD_PATH = 'upload/'

# ckeditor
CKEDITOR_CONFIGS = {
    # 将这份配置命名为 my_config
    'my_config': {
        'skin': 'moono-lisa',
        'toolbar_Basic': [
            ['Source', '-', 'Bold', 'Italic'],
            ['Maximize', 'ShowBlocks', '-'],
        ],
        'toolbar_Full': [
            ['Styles', 'Format', 'Bold', 'Italic', 'Underline', 'Strike', 'SpellChecker', 'Undo', 'Redo'],
            ['Link', 'Unlink', 'Anchor'],
            ['Image', 'Flash', 'Table', 'HorizontalRule'],
            ['TextColor', 'BGColor'],
            ['Smiley', 'SpecialChar'],
            # 在工具栏中添加该功能的按钮
            ['CodeSnippet'],
            ['Maximize'],
            ['Source'],


        ],
        'toolbar': 'Full',
        'height': 291,
        'width': 835,
        'filebrowserWindowWidth': 940,
        'filebrowserWindowHeight': 725,
        # 添加的插件
        'extraPlugins': 'codesnippet',
    }
}

urls.py

path('ckeditor', include('ckeditor_uploader.urls')),
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

18. 判断url

判断当前页面
class="{ % if request.path == '/resource/' % }current{ % endif % }"

19 . context上下文

[django]自定义全局context

  1. 创建一个context processor函数 新建一个文件命名为custom_processors.py,把它放到项目app文件夹(例如我的blog文件夹),添加一个返回字典的函数,其代码如下:
    from sets import Set
    from django.db.models import Count
    from .models import Category, Article
    def category(request):
     category = Category.objects.filter(article__status=0).values('name').annotate(
             num_article=Count('article'))
     return {'categories': category,}
    

    2.修改 settings 文件 打开项目的settings.py文件,添加如下代码:

     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',
                 'blog.custom_processors.category',
             ],
         },
     },
    ]
    
  2. 模板中添加自定义的变量 在要测试的模板里添加,访问的时候就会变成我们赋予其的值了,代码如下:
    { % for category in categories % }
     <li class="list-group-item">
     <span class="badge"></span>
    <a href="/category/"></a>
     </li>
    { % endfor % }
    

    由于在CONTEXT_PROCESSORS添加的函数在settings里,即使你不调用它,所有的views都自动调用它,可能会带来性能影响,请酌情使用