PythonWeb框架笔记

修改Mysql编码格式:
show variables like ‘character%’;
set character_set_database=utf8;
set character_set_server=‘utf8’;
-------------------------------------Django
导出环境:pip freeze > requirements.txt
sudo apt-get remove python-pip (卸载python2的pip)
sudo apt-get remove python3-pip (卸载3版本的pip3)
sudo apt-get install python3-pip (安装python3)
apt-get update (更新代码)
上线(简单):
sudo apt-get update
apt install python3-pip
pip freeze > requirements.txt 生成requirements.txt文件
pip3 install django==1.11
pip3 install -r requirements.txt
后台不间断:
apt install -y screen 安装
screen -S lnmp 创建一个lnmp的会话
screen -r lnmp 恢复到离开前创建的lnmp会话的工作界面、ctrl+a d 返回主页面
screen -ls 查看当前有哪些screen窗口
screen -X -S session quit 删除某个session
kill 9505 关闭指定的screen
python manage.py runserver 0.0.0.0:9000
上线(基础):
apt update 更新包
apt install python-dev python3-dev python-pip python3-pip
pip3 install --update pip
sudo apt-get install gcc
sudo pip3 install uwsgi uwsgi --version 来检查是否正确安装了
sudo apt-get install nginx

  • django命令
    运行django项目: python manage.py runserver
    创建django项目: django-admin startproject blog1
    创建django应用: python manage.py startapp blog2
    创建超级用户: python manage.py createsuperuser
    生成迁移文件: python manage.py makemigrations
    根据迁移文件创建数据库 python manage.py migrate

  • 静态文件
    在项目中创建static文件夹放置静态文件
    在setting.py下配置静态文件(2种方法)
    1.STATICFILES_DIRS = [ os.path.join(BASE_DIR,‘static’),]
    引用的静态文件路径必须是 /static/css/…
    2.直接引用静态文件的模版{% load static from staticfiles %}
    引用的静态文件路径必须是{% static ‘css/2.css’ %}

  • URL(路由)
    分发路由:url(r’’,include(‘xx.urls’))
    无命名分组(视图里面要接收参数):url(r’^xx/(\d{4})’,视图)
    有名分组(视图接收参数):url(r’^xx/(?P\d{4})’,视图)
    路由别名: url(r’^xx/(\d{4})’,视图,name=‘x’) {%url ‘x’%}
    from meduo_mall.demo import views
    url(r’register/$’, views.Demo.as_view())
    from django.views.generic import View
    class Demo(View):
    def get(self, request):
    return HttpResponse(‘get page’)
    def post(self, request):
    return HttpResponse(‘post page’)

  • 自定义404错误
    1.在setting中配置 DEBUG = False
    ALLOWED_HOSTS=["*"]
    2.在templates中编写404页面

  • 视图与模板
    HttpResponse(“xxxx”)
    render(request,‘x.html’,{‘xx’:x})
    render_to_response(‘x.html’,{‘xx’:x})
    render(request,‘x.html’,locals(将函数所有变量给模板))
    loads()
    def special(request):
    a1 = 123
    a2 = 456
    a3 = 789
    return render(request,‘index.html’,locals()) #跳转页面
    重定向(URL会发生改变)
    from django.http import HttpResponseRedirect
    return HttpResponseRedirect("/index/")
    跳转
    from django.shortcuts import redirect
    from django.urls import reverse
    return redirect(’/login’) redirect(view.x) redirect(reverse(‘blog:article_list’))
    request
    request.POST
    request.GET 获取HTTP GET方式请求传参,的参数(字典类型)request.POST.get(“name”)
    request.method 获取请求中使用的HTTP方式的字符串表示。全大写表示
    request.path 获取请求页面的全路径,不包括域名
    request.full_path() 获取HTTP GET方式请求传参,的URL地址
    模板
    变量: {{ var_name }}
    过滤器: {{ obl | fifter:param }}
    注释: {# #}
    标签: {% csrf_token %} {% url %}
    {% if condition %} … {% endif %}
    {% for %} … {% endfor %}
    {% ifequal var1 var2 %} … {% endifequal %}
    {% include “nav.html” %}
    继承: {% block mainbody %} … {% endblock %}
    {% extends “x.html” %} {% block mainbody %} … {% endblock %}

  • model(数据库模型)
    配置mysql数据库
    init.py导入MySQL
    import pymysql
    pymysql.install_as_MySQLdb()
    DATABASES = {
    ‘default’: {
    ‘ENGINE’: ‘django.db.backends.mysql’,
    ‘NAME’: ‘test’,
    ‘USER’: ‘root’,
    ‘PASSWORD’: ‘123456’,
    ‘HOST’:‘localhost’,
    ‘PORT’:‘3306’,}}
    创建表
    class Test(models.Model):
    name = models.CharField(max_length=20,verbose_name=‘姓名’)
    age = models.IntegerField(‘年龄’,null=True,Blank=True)
    nd =models.Charfield(choices=((‘cj’,‘初级’),(‘zj’,‘中级’),(‘gj’,‘高级’)),verbose_name=‘难度’) obj.get_字段名称_display
    定义了auto_now_add或auto_now属性,那么这种列不会在admin的页面中显示
    time1=models.DateField(auto_now=True) 每次更新都会更新 auto_created=False  自动创建
    time2=models.DateTimeField(auto_now_add=True) 永远是创建时的时间
    可以在列的定义语句后增加设置editable属性为True(最新版本已经删除了editable无法显示) update_time.editable = True
    或者 admin中添加 readonly_fields = (‘save_date’, ‘mod_date’,)
    models.BooleanField(Blank=True)允许admin后台中为空
    class Meta:
    verbose_name = ‘用户表’ #设置表名称在django后台显示的中文名称
    verbose_name_plural = verbose_name
    def str(self): #设置在django后台显示字段名称
    return self.anem
    链表操作
    一对多:models.ForeignKey(其他表)
    多对多:models.ManyToManyField(其他表)
    一对一:models.OneToOneField(其他表)
    数据库操作(通过views)
    from .models import *
    添加
    1.test1 = Test(name=‘shouce.ren’)
    test1.save()
    2.Test.objects.create(name=‘xxx’)
    3.dic = {‘user’:‘yangmv’,‘pwd’:‘123456’}
    Test.objects.create(**dic)
    查询
    1.list = Test.objects.all()
    for var in list:
    print(var.name)
    2.Test.objects.filter(name=“x”).order_by(“id”)
    3.Test.objects.filter(id__gt=1)获取指定条件的数据 .get(id=2) .first() .last() .count()
    __gt 大于 __gte 大于等于 __lt 小于 __lte 小于等于
    4.order_by()排序,参数:‘字段名’ 称升序、’-字段名’ 称降序
    修改
    1.test1 = Test.objects.get(id=1)
    test1.name = ‘菜鸟教程’
    test1.save()
    2.Test.objects.filter(id=1).update(name=‘教程’)
    3.Test.objects.all().update(name=‘教程’)
    删除
    1.test1 = Test.objects.get(id=1)
    test1.delete()
    2.Test.objects.filter(id=1).delete()
    3.Test.objects.all().delete()
    多表操作(一对一) OneToOneField()外键链表,一对一类型,也就是相当于,在外键字段加了一个唯一索引,在添加数据时不能有重复类容,只能一对一
    多表操作(一对多) 正向查找,也就是通过表的外键,查找到外键连接的表里的数据 __双下划线跨表查询必须是外键连接的表
    反向查找,从一张表查到它,被那张表外键连接,然后查出外键连接表里的信息 外键表类名称_set,链表反向查找 外键表类名称__外键表字段
    添加
    1.Book.objects.create(name=‘x’,publish_id=2)
    2.pub=Pub.objects.fifter(name=‘xx’)
    Book.objects.create(name=‘xx’,publish=pub)
    查询
    1.pub=Pub.objects.filter(name=‘x’)[0]
    ret=Book.objects.filter(publish=pub).value(‘name’)
    2.Book.objects.fifter(publish_id=cid)
    删除
    cid = input(‘班级ID’) cnd = input(‘班级名称’)
    1.Student.objects.fifter(cs_id=cid).delete()
    2.Student.objects.fifter(cs__name=cnd).delete()
    修改
    1.Student.objects.fifter(cs_id=cid).update()
    2.Student.objects.all().update(cs_id=cid)
    多表操作(多对多)
    m = models.ManyToManyField(“Teachers”)
    obj = Classes.objects.fifter(id=1).first()
    # 添加
    obj.m.add(1)
    obj.m.add([2,3])
    # 删除
    obj.m.remove([2,3])
    # 清空
    obj.m.clear()
    # 重置
    obj.m.set([2,3,5])
    # 查询
    ret = obj.m.all()
    ret = obj.m.filter()

  • admin
    注册
    1.admin.site.register(Test)
    2.admin.site.register([Test, Contact, Tag])
    列表显示
    1.class ArticleAdmin(admin.ModelAdmin):
    list_display = (‘title’,‘pub_date’,‘update_time’)配置要显示的字段
    admin.site.register(Article,ArticleAdmin)
    2.@admin.register(Blog)
    class BlogAdmin(admin.ModelAdmin):
    #listdisplay设置要显示在列表中的字段(id字段是Django模型的默认主键)
    list_display = (‘id’, ‘caption’, ‘author’, ‘publish_time’)
    #list_per_page设置每页显示多少条记录,默认是100条
    list_per_page = 50
    #ordering设置默认排序字段,负号表示降序排序
    ordering = (’-publish_time’,)
    #list_editable 设置默认可编辑字段
    list_editable = [‘machine_room_id’, ‘temperature’]
    #search_fields 为该列表页增加搜索栏
    search_fields = (‘name’,)
    #list_filter 对显示结果进行过滤
    list_filter = [‘publish_time’]
    #fk_fields 设置显示外键字段
    fk_fields = (‘machine_room_id’,)
    自定义表单
    1.class ContactAdmin(admin.ModelAdmin):
    fields = (‘name’, ‘email’)
    admin.site.register(Contact, ContactAdmin)
    2.class ContactAdmin(admin.ModelAdmin):
    fieldsets = ( [‘Main’,{ ‘fields’😦‘name’,‘email’), }],)
    admin.site.register(Contact, ContactAdmin)
    调整页面头部显示内容和页面标题
    class MyAdminSite(admin.AdminSite):
    site_header = ‘好医生运维资源管理系统’ # 此处设置页面显示标题
    site_title = ‘好医生运维’ # 此处设置页面头部标题
    admin_site = MyAdminSite(name=‘management’)
    界面汉化
    LANGUAGE_CODE = ‘zh-hans’
    TIME_ZONE = ‘Asia/Shanghai’

  • cookies
    操作cookie
    获取cookie: request.COOKIES[‘xx’]
    设置cookie: request.set_cookie[‘xx’,value]
    操作session(默认保存15天)
    获取session: request.session[‘xx’] session.get(‘username’, ‘’)
    设置session: request.session[‘xx’]=value
    删除session: del request.session[‘xx’]
    设置过期时间: request.session.set_expiry (value)
    返回会话过期秒数: request.session.get_expiry_age()
    返回会话结束日期: request.session.get_expiry_date()

  • 数据库缓存
    python manage.py createcachetable my_cache_table
    CACHES = {
    ‘default’: {
    ‘BACKEND’: ‘django.core.cache.backends.db.DatabaseCache’,
    ‘LOCATION’: ‘my_cache_table’,
    ‘TIMEOUT’: 60 * 5,
    }}
    from django.views.decorators.cache import cache_page
    @cache_page(30)
    def index(request):

  • redis缓存
    pip install django-redis
    pip install django-redis-cache

    CACHES = {
    “default”: {
    “BACKEND”: “django_redis.cache.RedisCache”,
    “LOCATION”: “redis://127.0.0.1:6379”,
    “OPTIONS”: {
    “CLIENT_CLASS”: “django_redis.client.DefaultClient”,
    “CONNECTION_POOL_KWARGS”: {“max_connections”: 100}
    }

  • Ajax
    Ajax向后台发送请求:
    1.下载jQuery
    2.$.ajax({
    url:’/add.html’,
    type:‘GET’,
    data:{‘name’:‘xx’,‘pwd’:‘123’} /data: $(“form”).serialize(),
    success:function(arg){
    //回调函数 arg是服务端返回的数据

      	}
      	}) 
    
  • 分页
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    article_list = Article.objects.all()
    paginator = Paginator(article_list, 10) # 实例化一个分页对象, 每页显示10个
    page = request.GET.get(‘page’) # 从URL通过get页码,如?page=3

    Paginator常用属性

    per_page: 每页显示条目数量

    count: 数据总个数

    num_pages:总页数

    page_range:总页数的索引范围,页码的范围,从1开始,例如[1, 2, 3, 4]

    try:
    articles = paginator.page(page) # 获取某页对应的记录
    except PageNotAnInteger: # 如果页码不是个整数
    articles = paginator.page(1) # 提取第一页的记录
    except EmptyPage: # 如果页码太大,没有相应的记录
    articles = paginator.page(paginator.num_pages) # 提取最后一页的记录
    return render(request, ‘’, {‘articles’: articles})

    articles = paginator.page()

    has_next 是否有下一页

    next_page_number 下一页页码

    has_previous 是否有上一页

    previous_page_number 上一页页码

    object_list 分页之后的数据列表,切片好的数据

    number 当前页

    paginator paginator对象

    {% for page in all_org.paginator.page_range %}
    {% if page == all_org.number %}

  • {{ page }}

  • {% else %}
  • {{ page }}

  • {% endif %}
    {% endfor %}

  • Form组件
    from django import forms
    class Form1(forms.Form):
    img = forms.FileField()
    city = forms.ChoiceField(choices=[(1,‘sh’),(2,‘bj’)])
    hobby=forms.MultipleChoiceField(choices=[(1,‘sh’),(2,‘bj’)])
    user = forms.CharField(max_length=18,min_lenth=6,required=True)
    pwd = forms.CharField(required=True,error_message={
    ‘required’:‘密码不能为空’,},widget=forms.PasswordInput()
    label=‘密码’,initial=‘初始值’)
    age = forms.IntegerField(required=True,error_message={
    ‘invalid’:‘格式错误必须为数字’,})
    email= forms.EmailField(required=True)

    is_valid()返回验证是否通过的布尔值

    cleaned_data获取验证通过后的所有提交数据,返回字典

    errors获取验证错误信息,返回所有表单的错误信息对象

    f = Form1(request.POST)
    if f.is_valid():
    print(f.cleaned_data)
    else:
    print(f.errors)
    f.errors.username

  • 序列化
    from django.core import serializers
    ret = models.BookType.objects.all()
    data = serializers.serialize(“json”, ret)

  • 上传文件
    方式一:

    obj = request.FILES.get(‘img’)
    f.open(obj.name,‘wb’)
    for chunk in obj.chunks():
    f.write(chunk)
    f.close()
    # .read():从文件中读取整个上传的数据,这个方法只适合小文件
    # .chunks():按块返回文件,通过在for循环中进行迭代,可以将大文件按块写入到服务器中
    # .multiple_chunks()根据myFile的大小,返回True或者False,当myFile文件大于2.5M,True
    # .name:这是一个属性
    # .size:这也是一个属性
    models上传:
    class UserModel(models.Model):
    name = models.Charfield(max_length=16)
    icon = models.ImageField(upload_to=‘icon/%Y/%m/%d’) # upload_to相当于媒体文件MEDIA_ROOT根目录
    MEDIA_ROOT = os.path.join(BASE_DIR, ‘upload’)
    if request.method == ‘POST’:
    username = request.POST.get(‘username’)
    icon = request.FILES.get(‘icon’)
    user = UserModel()
    user.username = username
    user.icon = icon
    user.save()
    print(user.icon.url)
    Form组件上传:
    class UserForm(forms.Form):
    user = forms.CharField()
    img = forms.FileField()
    if request.method == “POST”:
    obj = UserForm(request.POST,request.FILES)
    if obj.is_valid():
    user = obj.cleaned_data[‘user’]
    img = obj.cleaned_data[‘img’]
    f = open(img.name,‘wb’)
    for line in img.chunks():
    f.write(line)
    f.close()
    Ajax上传:

  • 验证码
    pip install Pillow
    pip install django-simple-captcha
    url(r’^captcha/’, include(‘captcha.urls’)),
    from django import forms
    from captcha.fields import CaptchaField
    class CaptchaForm(forms.Form):
    captcha = CaptchaField(label=u"验证码")
    {{ captcha }}
    {% if captcha_error %}
    form = CaptchaForm(request.POST)
    if form.is_valid():
    pass
    else:
    ret[‘captcha_error’] = “验证码错误”
    success_flag = False
    ret[‘captcha’] = CaptchaForm()

  • xadmin(第三方后台管理)

    配置

      'xadmin',#settings中INSTALLED_APPS添加    
      'crispy_forms',#INSTALLED_APPS添加添加
      xadmin sites.py 中 注释sys.setdefaultencoding("utf-8")
      url(r'^xadmin/', xadmin.site.urls)
    

    注册

      import xadmin
      from app import models
      class BannerAdmin(object):
          list_display = ['title','image','url','index','add_time'] 设置数据表在后台显示的字段
          search_fields = ['title','image','url','index']			  设置在后台可以搜素的字段
          list_filter = ['title','image','url','index','add_time']  设置在后台可以通过条件帅选查看的字段
          list_filter = ['course__name', 'name', 'add_time']        course__name 表示通过course外键字段查询关联表里的name字段
      xadmin.site.register(Banner,BannerAdmin)                      将制定表注册到xadmin后台
    

    更换xadmin默认主题

      from xadmin import views 
      class BaseSetting(object):
          enable_themes = True
          use_bootswatch = True
      xadmin.site.register(views.BaseAdminView,BaseSetting)
    

    修改左上角和底部logo

      class GlobalSettings(object):                               # 头部系统名称和底部版权管理器
          site_title = '玉秀管理系统'                              # 头部系统名称
          site_footer = '玉秀管理系统,玉秀公司版权所有'             # 底部版权
          menu_style = 'accordion'                                # 设置数据管理导航折叠,以每一个app为一个折叠框
              # 设置models的全局图标
          global_search_models = [UserProfile, Sports]
          global_models_icon = {
      	UserProfile: "glyphicon glyphicon-user", Sports: "fa fa-cloud" }                                
      xadmin.site.register(views.CommAdminView, GlobalSettings)   # 头部系统名称和底部版权管理器绑定views.CommAdminView注册
    

    导航app名称设置成中文

      	1.在当前app目录下的apps.py文件里配置后台要显示的中文名称
      	from django.apps import AppConfig
      		class AppCoursesConfig(AppConfig):
      		    name = 'app_courses'            # 当前app名称
      		    verbose_name = '课程管理'        # 要设置的中文名称
      	2.在当前app目录下的__init__.py文件里应用app中文名称设置类的路径
      		default_app_config = app中文名称设置类的路径,从app开始到类
      		default_app_config = 'app_courses.apps.AppCoursesConfig'
    
  • Xadmin集成富文本框(DjangoUeditor3)
    首先安装DjangoUeditor3模块
    os.path.join(BASE_DIR,‘extra_apps’)
    将DjangoUeditor文件夹,整个文件夹复制到Xadmin同级目录
    安装好后在settings.py将DjangoUeditor添加到app
    url(r’^ueditor/’,include(‘DjangoUeditor.urls’ ))
    在models.py文件,在要使用富文本框的字段使用UEditorField
    from DjangoUeditor.models import UEditorField
    class Course(models.Model):
    name = models.CharField(max_length=50, verbose_name=‘课程名称’)
    desc = models.CharField(max_length=300, verbose_name=‘课程描述’)
    detail = UEditorField(verbose_name=‘内容’,
    width=900,height=300,
    imagePath=“neird/tup/”,
    filePath=“neird/wjian/”,
    default=’’,
    toolbars=‘mini’)
    在adminx.py文件里找到对应的数据表管理器,在管理器里指定字段用富文本框
    style_fields = {‘字段名称’:‘ueditor’}指定字段使用富文本框

  • 发送邮件

    配置邮箱发邮件的相关功能settings

    #这一项是固定的
    EMAIL_BACKEND = ‘django.core.mail.backends.smtp.EmailBackend’

    smtp服务的邮箱服务器 我用的是163

    EMAIL_HOST = ‘smtp.163.com’

    smtp服务固定的端口是25

    EMAIL_PORT = 465
    EMAIL_USE_SSL = True
    #发送邮件的邮箱
    EMAIL_HOST_USER = ‘18438603979@163.com’
    #在邮箱中设置的客户端授权密码
    EMAIL_HOST_PASSWORD = ‘xxx’
    #收件人看到的发件人 <此处要和发送邮件的邮箱相同>
    EMAIL_FROM = ‘18438603979@163.com’
    from django.core.mail import send_mail
    send_mail(email_title,email_body,settings.EMAIL_FROM,[email])

    1. import smtplib
      from email.mime.text import MIMEText

      邮件服务器

      mail_server = ‘smtp.qq.com’

      用户名

      mail_username = ‘1337983798@qq.com’

      密码,通过环境变量获取,可以避免隐私信息的暴露

      或授权码,QQ邮箱需要使用授权码

      mail_password = ‘fxtlwernbugpbadd’

      邮件内容

      content = ‘QQ:1337983798’
      ‘微信:18438603979’

      创建用于发送的邮件消息对象

      参数1:邮件内容

      参数2:内容类型,plain表示普通文本,html表示网页

      message = MIMEText(content)

      设置主题

      message[‘Subject’] = ‘联系方式邮件’

      设置发送者

      message[‘From’] = mail_username

      创建用于发送邮件的对象

      SMTP:邮件不加密,端口25

      SMTP_SSL:邮件加密传输,端口465,QQ邮箱必须使用加密

      mail = smtplib.SMTP(mail_server)

      身份认证

      mail.login(mail_username, mail_password)

      发送给谁

      to = user

      发送邮件

      mail.sendmail(mail_username, to, message.as_string())

      结束

      mail.quit()

  • 用户激活

    1. from random import Random # 导入随机函数
      from django.core.mail import send_mail # 导入django邮件函数
      from app_users.models import Email # 导入激活操作数据库表
      from MxOnline.settings import DEFAULT_FROM_EMAIL

      def random_str(randomlength=8):
      “”"
      循环获取随机字符串,默认8位
      “”"
      str = ‘’
      chars = ‘AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789’
      length = len(chars) - 1
      random = Random()
      for i in range(randomlength):
      str+=chars[random.randint(0, length)]
      return str

      def send_register_email(email, send_type=“register”):
      “”"
      发送邮件
      :接收两个参数:
      :第一个验证邮箱,第二个验证类型
      “”"
      “”“写入数据库验证信息”""
      email_record = Email() # 实例化数据库表
      if send_type == “update_email”:
      code = random_str(4) # 生成4位随机数
      else:
      code = random_str(16) # 生成16位随机数
      email_record.code = code # 数据库写入验证随机数
      email_record.email = email # 数据库写入验证邮箱
      email_record.send_type = send_type # 数据库写入验证类型
      email_record.save()

       """发送验证邮件"""
       email_title = ""                                    # 记录邮件标题
       email_body = ""                                     # 记录邮件内容
      
       if send_type == "register":
           email_title = "慕学在线网注册激活链接"
           email_body = "请点击下面的链接激活你的账号: http://127.0.0.1:8000/active/{0}".format(code)
      
           send_status = send_mail(email_title, email_body, DEFAULT_FROM_EMAIL, [email])
           if send_status:
               pass
       elif send_type == "forget":
           email_title = "慕学在线网注册密码重置链接"
           email_body = "请点击下面的链接重置密码: http://127.0.0.1:8000/reset/{0}".format(code)
      
           send_status = send_mail(email_title, email_body, DEFAULT_FROM_EMAIL, [email])
           if send_status:
               pass
       elif send_type == "update_email":
           email_title = "慕学在线邮箱修改验证码"
           email_body = "你的邮箱验证码为: {0}".format(code)
      
           send_status = send_mail(email_title, email_body, DEFAULT_FROM_EMAIL, [email])
           if send_status:
               pass
      

    2.设置激活连接逻辑
    url(r’^active/(?P<active_de>.*)/$’, active_code.as_view(), name=“user_active”)
    class active_code(View):
    def get(self, request, active_de):
    yanzh_email = Email.objects.filter(code=active_de)
    if yanzh_email:
    for record in yanzh_email:
    email = record.email
    Users.objects.filter(username=email).update(is_active=True)
    Email.objects.filter(code=active_de).delete()
    return render(request, ‘login.html’)

  • media保存上传文件(不存储在数据库)
    MEDIA_URL = ‘/media/’ # setting 设置媒体文件的相对路径
    MEDIA_ROOT = os.path.join(BASE_DIR, ‘media’) # setting 设置媒体文件的绝对路径
    ‘django.template.context_processors.media’, # setting TEMPLATES添加
    img = models.ImageField(upload_to=‘user/image/%Y/%m’) #model media/user/image/%Y/%m
    #url 处理Django静态文件
    from django.views.static import serve

    配置上传文件的访问处理函数

    url(r’^media/(?P .*)$’, serve, {‘document_root’: MEDIA_ROOT}),

    模版里配置

  • markdown
    import markdown
    from django.shortcuts import render, get_object_or_404
    from .models import Post

    def detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    # 记得在顶部引入 markdown 模块
    post.body = markdown.markdown(post.body,
    extensions=[
    ‘markdown.extensions.extra’,
    ‘markdown.extensions.codehilite’,
    ‘markdown.extensions.toc’,
    ])
    return render(request, ‘blog/detail.html’, context={‘post’: post}) # {{ post.body|safe }}
    ## 我是标题一
    这是标题一下的正文
    ## 标题二
    这是标题二下的正文
    ### 我是标题二下的子标题
    这是标题二下的子标题的正文
    ## 我是标题三
    这是标题三下的正文

  • 中间件

-------------------------------------Flask--------------------------------------------------------

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值