Django学习笔记

1、安装django

pip install -U django #安装django
 

2、创建django工程、启动工程

创建项目
django-admin startproject django_test 
#安装完django后会有django-admin命令
#django_test是项目名称,创建项目时修改为自己的项目名称即可
启动项目

项目创建完成后,会在执行命令的目录下产生一个项目同名的目录,进入到这个项目执行命令就可以启动了,命令如下:

cd django_test
python manage.py runserver #启动工程,默认端口号8000
启动后访问 127.0.0.1:8000 即可看到django初始页面,如下图:

 

3、django目录说明

 

 
 

4、初始化配置

项目创建好后,有一些初始化的配置需要修改,在setting.py

下面是要默认的配置
# LANGUAGE_CODE = 'en-us'
#默认语言 # TIME_ZONE = 'UTC'
#当前时区 # USE_TZ = True
#是否使用默认时区
#修改为下面的配置
LANGUAGE_CODE = 'zh-Hans'  #中文
TIME_ZONE = 'Asia/Shanghai' #亚洲的时区
USE_TZ = False #不使用默认是时区
修改完成后,再刷新前面的初始化页面,可以看到都是中文的了。

 

如果要使用mysql数据库,除了修改setting文件中的配置外,还需要在和setting文件同目录下的__init__.py文件中配置如下内容:
import pymysql
pymysql.install_as_MySQLdb()
 

5、创建app

我们在写业务代码时,一般按照业务/工程划分模块,所以在写代码之前要先创建好一个模块,在django里面称为application,也就是app,命令如下:

python manage.py startapp user #创建一个user模块
注意:创建完app后,一定要在settings中的INSTALLED_APPS配置上这个app
INSTALLED_APPS = [    
'django.contrib.admin',    
'django.contrib.auth',    
'django.contrib.contenttypes',    
'django.contrib.sessions',    
'django.contrib.messages',    
'django.contrib.staticfiles',    
'user', #新创建的app ]
创建完在工程目录下就多了一个user的目录,结构如下:

 

 
 

6、编写第一个view

接下来就可以编写第一个view了, 也就是我们的业务代码,在user里面的views.py里面定义一个函数,代码如下:

from django.http.response import HttpResponse
#导入HttpResponse,如果要返回一个字符串的话,要用HttpResponse才可以


def index(request):  # request这个参数是必须要写的
    msg = "hello world!"    
    return HttpResponse(msg)
 

7、配置urls

逻辑写完之后,客户端需要通过url来访问,就需要在urls里面配置上映射,配置一个url来对应上面写的index

from django.contrib import admin 
from django.urls import path 
from user import views 
#从user模块中导入views 

urlpatterns = [     
    path('admin/', admin.site.urls),#默认的配置,是django后端管理的     
    path('index', views.index),#这个是新配置的,url是index,访问这个url后就找到了前面写的index函数
]
 

8、测试view

访问 http://127.0.0.1:8000/index,可以看到访问到了前面写的view,展示了hello world

 
 

9、初始化命令总结

django-admin startproject project_name #创建项目 
python manage.py startapp app_name #创建app 
python manage.py runserver #启动项目 
python manage.py runserver 8999 #指定端口号启动  只能本机访问 
python manage.py runserver 0.0.0.0:8999 #别人通过你的IP地址也可以访问

10、静态文件配置

静态文件配置需要中setting文件中增加如下配置:
STATICFILES_DIRS = (os.path.join(BASE_DIR,'static'),)#静态文件目录
配置完成后,需要注意修改templates中的html里的静态文件地址,需要和配置相对应

11、生成表结构

需要在models文件中创建相应的类,例子如下:
from django.db import models 
class Article(models.Model):
    title = models.CharField(verbose_name='文章标题',max_length=100,db_index=True)     
    desc = models.CharField(verbose_name='描述',max_length=100,blank=True,null=True,default='这个文章没有描述')     
    content = models.TextField(verbose_name='文章内容')     
    img = models.ImageField(verbose_name='文章图片',upload_to='article_img',default='images/1.jpg')  # pip install pillow  article_img/%Y/%m  settings里设置上传地址     
    recommend = models.BooleanField(verbose_name='是否推荐',default=False)     
    category = models.ForeignKey(Category,verbose_name='分类',on_delete=models.DO_NOTHING,db_constraint=False)     
    # models.CASCADE  #级联删除     # db_constraint  不会真正在数据库里面建立外键     
    create_time = models.DateTimeField(verbose_name='创建时间', auto_now_add=True)     
    update_time = models.DateTimeField(verbose_name='修改时间', auto_now=True)     
    is_deleted = models.BooleanField(verbose_name='是否删除', default=False)     
    
    class Meta:
        db_table = 'article' #数据库中的表名称         
        ordering = ['create_time'] #排序         
        verbose_name = '文章'         
        verbose_name_plural = verbose_name  #设置之后在后台可以按verbose_name显示     
    
    def __str__(self):
        return self.title  #查询结果在后台按title显示
类创建完成后需要再通过命令行执行下面两个命令
python manage.py makemigrations 
python manage.py migrate

12、views查询数据

例子如下
from django.shortcuts import render,HttpResponse,get_object_or_404,Http404 
from .models import Category,Article 
from django.core.paginator import Paginator 
from . import const 

# Create your views here. 

def index(request):
    # catagories = Category.objects.filter(is_deleted=False)     
    category_id = request.GET.get('category_id',1)     
    page = request.GET.get('page',1)     
    limit = request.GET.get('limit',const.page_size)     
    article = Article.objects.filter(is_deleted=False,category_id=category_id)     
    page_obj = Paginator(article,limit)     
    page_data = page_obj.page(page)     
    # data = {'nav':catagories,'articles':article}     
    data = {'articles':page_data}     
    return render(request,'index.html',data)

13、后台管理

1、执行下面的命令创建超级管理员账号
python manage.py createsuperuser
根据提示填写相关内容,完成后可以登录Django的后台管理页面

14、orm单表增删改查

示例代码如下,创建一个文件,和model文件同级
import django,os 

os.environ.setdefault('DJANGO_SETTINGS_MODULE','dj_test.settings') 
django.setup() 

from user.models import Category,Article 

#增加 
c_obj = Category.objects.create(name="Mysql") 
print(c_obj.name) 
print(c_obj.create_time) 
print(c_obj.update_time) 
obj = Category(name='Oracel') 
obj.save() 

#查询 
print(Category.objects.all()) 
print(Category.objects.get(id__gt=1))  #get() returned more than one Category -- it returned 4! 
print(Category.objects.get(name="Mysql")) 
print(Category.objects.get(name="Linux")) 
print(Category.objects.filter(id__gte=1)) 
print(Category.objects.filter(id__gte=1,name="Linux")) 
print(Category.objects.exclude(name="Linux").filter(id__gt=3)) 

#修改 
Category.objects.update(name="xxx") 
Category.objects.update(is_deleted=True) 
obj = Category.objects.get(id=1) 
obj.is_deleted = False 
obj.save() 
Category.objects.filter(id__in=[2,3,4]).update(is_deleted=False) 

#删除 
Category.objects.all().delete() 
obj = Category.objects.get(id=1) 
obj.delete() 
obj.save() 
Category.objects.filter(id__in=[2,3,4]).delete(is_deleted=False)

15、上传文件

上传文件需要在setting文件中配置如下参数
MEDIA_ROOT = os.path.join(BASE_DIR,'static')#上传文件默认存放路径
然后结合model类中的upload_to字段结合形成最终上传地址
img = models.ImageField(verbose_name='文章图片',upload_to='article_img',default='images/1.jpg')  # pip install pillow  article_img/%Y/%m  settings里设置上传地址
最终上传地址目录如下图

16、实现分类页面

原来是通过category去访问的方式实现查看分类页面的,后续优化代码的时候将可以合并的地方都合并了,可以参考index的代码,这里只是展示之前的实现方式
在url中配置
urlpatterns = [     
    path('admin/', admin.site.urls),     
    path('index/', index),     
    path('', index),     
    # path('category/<int:id>', category),     
    path('detail/', detail,name='detail'), 
]
在view中配置
def category(request,id):
    # catagories = Category.objects.filter(is_deleted=False)     
    article = Article.objects.filter(is_deleted=False,category_id=id)     
    # data = {'nav':catagories,'articles':article}     
    data = {'articles':article}     
    return render(request,'index.html',data)
这种方式是需要通过/id的方式去访问的,和之后的实现方式要区别开来。

17、上下文管理器

1、每个view里面都需要用到的操作,可以放到上下文管理器里面查
2、先定义一个函数,函数必须有一个参数request
3、这个函数要返回一个字典
文件和models文件在同一目录下,名字是process_content.py
from . import models 
def category_process(request):
    categories = models.Category.objects.filter(is_deleted=False)     
    return {'nav':categories}     
    # return locals()  如果不想规定返回的字典的key,可以用这种方式
4、要在配置文件里面配置,在TEMPLATES的OPTIONS中增加这个函数user.process_content.category_process
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',                
                'user.process_content.category_process',             
            ],        
        },    
    }, 
]
 

18、模板继承

1、一些公用的html代码可以放在一个模板文件中,并在与其他html文件有区别的地方用代码标记,一遍有content、js和css
{% block css %}     
{% endblock %}         

{% block content %} 
{% endblock %} 

{% block js %} 
{% endblock %}
2、在其他html文件中引用这个模板,需要在代码中加入extends声明引入的模板文件,并且在对应的模板位置引入不同代码
{% extends 'base.html' %} 

{% block css %}     
<link href="/static/css/info.css" rel="stylesheet"> 
{% endblock %} 

{% block content %} 
<article> 。。。。。。。 
</article> 
{% endblock %}
上面的例子中article的内容就是该html文件特有的内容,其作为content内容填充到模板标记的content位置。

19、分页

分页的后端方法如下
from django.core.paginator import Paginator 

l = range(1,51) 
page_obj = Paginator(l,10) 
page_obj = Paginator(Article.objects.all(),2) 

print(page_obj.page(1)) #取某一页数据 
print(list(page_obj.page(3))) 
print(list(page_obj.get_page(1))) 

print(page_obj.count)  #总共多少条 
print(page_obj.num_pages)  #共分了几页 
print(page_obj.page_range)  #分页的范围 

cur_page = page_obj.page(2) 
print(cur_page.has_previous())  #判断有没有上一页 
print(cur_page.previous_page_number())  #获取上一页的页码 
print(cur_page.has_next())  #判断有没有下一页 
print(cur_page.next_page_number())  #获取下一页的页码 
print(cur_page.has_other_pages())  #是否有其他页 
print(cur_page.paginator)
分页的前端方法如下
{% if articles.has_other_pages %}     

<div class="pagelist">         
    {% if articles.has_previous %}         
    <a class="allpage" href="/index?page={{ articles.previous_page_number }}&limit=10"><b>上一页</b></a>&nbsp;&nbsp;             
    {% endif %}         
    
    {% for page_num in articles.paginator.page_range %}         
    <a href="/index?page={{ page_num }}&limit=10" >{{ page_num }}</a>&nbsp;&nbsp;         
    {% endfor %}         
    
    {% if articles.has_next %}         
    <a href="/index?page={{ articles.next_page_number }}&limit=10" >下一页</a>             
    {% endif %}     
</div>     

{% endif %}
里面特色的地方在于page_range不是当前页的属性,而是分页对象的属性,所以需要通过paginator字段来获取分页对象,articles.paginator.page_range

20、优化和丰富Django admin

在admin文件中配置如下内容,可以在后台展示更多的字段和增加搜索、过滤、分页等功能
from django.contrib import admin 
from . import models 

# Register your models here. 

class ArticleAdmin(admin.ModelAdmin):
    list_display = ['title','category','create_time','update_time'] #显示哪些字段     
    search_fields = ['title']  #以哪些字段搜索,不要写外键     
    list_filter = ['category','is_deleted']    #以哪些字段过滤     
    list_per_page = 10      #分页,每页显示多少条 
    
class CategoryAdmin(admin.ModelAdmin):
    list_display = ['name','create_time','update_time'] #显示哪些字段     
    search_fields = ['name']  #以哪些字段搜索,不要写外键     
    list_filter = ['is_deleted']    #以哪些字段过滤     
    list_per_page = 10      #分页,每页显示多少条 
    
class MyAdminSite(admin.AdminSite):
    site_header = 'xxx后台管理'     
    site_title = 'xxxx后台管理' 
    
# site = MyAdminSite() 
# site.register(models.Category,CategoryAdmin) 
# site.register(models.Article,ArticleAdmin) 

admin.site.register(models.Category,CategoryAdmin) 
admin.site.register(models.Article,ArticleAdmin)

如果想使用新的UI界面,可以通过下面的命令安装
pip install simpleui
然后在setting中配置simpleui
INSTALLED_APPS = [     
    'simpleui',     
    'django.contrib.admin',     
    'django.contrib.auth',     
    'django.contrib.contenttypes',     
    'django.contrib.sessions',     
    'django.contrib.messages',     
    'django.contrib.staticfiles',     
    'user.apps.UserConfig', 
]

21、前端自定义标签

该应用应包含一个 templatetags 目录,与 models.py, views.py 等同级。若该目录不存在,创建它——不要忘了用 __init__.py 文件确保目录被视作一个 Python 包。
开发服务器并不会自动重启 添加 templatetags 模块后,你需要重启服务器,这样才能在模板中使用 tags 和 filters。

自定义的 tags 和 filters 会保存在模块名为 templatetags 的目录内。模块文件的名字即稍候你用来加载 tags 的名字,所以小心不要采用一个可能与其它应用自定义的 tags 和 filters 冲突的名字。

 
在模板中你会使用以下代码:
{% load poll_extras %}

为了使 {% load %} 标签生效,包含自定义标签的应用必须包含在 INSTALLED_APPS 中。这是个安全特性:它允许你在一个主机上持有多个模板库,而不是让每个 Django 安装都能访问所有的库。

要成为一个可用的 tag 库,模块必须包含一个名为 register 的模块级变量,它是一个 template.Library 实例。所有的 tags 和 filters 均在其中注册。所以,在模块的开始,输入以下内容:

from django import template 

register = template.Library()

my_tag示例

from django import template 

register = template.Library() 

@register.filter  #最多就2个参数 
def jieduan(s):
    if len(s)>10:         
        s = s[:11]+'...'     
    return s 

@register.simple_tag  #不限制参数 
def jieduan2(s,):
    if len(s)>20:         
        s = s[:21]+'...'
    return s
作用是截断过长的字符串,在html文件中需要下面这样使用
<p>{{arcl.desc | jieduan:20}}</p>  #该方式最多有两个参数,第一个在|之前,第二个参数在函数之后 
<p>{%  jieduan2 arcl.desc 20%}</p>  #该方式不限制参数数量,具体参考tag示例

Django自带的一些tag用法

例如设置时间的格式,可以直接使用|date:参数来设置,参考info页面
<li class="timer">{{ article.create_time|date:'Y-m-d D'}}</li>
<p>{{ h1_str| safe}}</p> 
{#xss注入#}
    
#可以防止xss注入,例子参考视频,加上safe之后,浏览器会按照html标签来解析,不加的时候不会按html标签来解析。

22、form

待续

posted @ 2023-06-15 21:39  狂爷  阅读(52)  评论(0编辑  收藏  举报