Django学习

一、介绍&&初识

    django是一个开源的web框架,由python编写。django的mtv模式:

Model(模型):负责业务对象与数据库的对象(ORM)
Template(模版):负责如何把页面展示给用户
View(视图):负责业务逻辑,并在适当的时候调用Model和Template

    django还有一个url分发器,它的作用是将一个个URL的页面请求分发给不同的view处理,view再调用相应的Model和Template

二、Django流程以及常用命令

创建project
django-admin startproject mysite
创建APP
python mannage.py startapp  appname
启动项目
python manage.py runserver  127.0.0.1:8090
生成同步数据库的脚本
python manage.py makemigrations 
同步数据库
python manage.py migrate  
创建超级管理员
python manage.py createsuperuser
启动交互界面
python manage.py  shell
简单项目实例

1、创建项目

django-admin.py startproject mysite

    当前目录下会生成mysite的工程,目录结构如下:

manage.py ----- Django项目里面的工具,通过它可以调用django shell和数据库等。
settings.py ---- 包含了项目的默认设置,包括数据库信息,调试标志以及其他一些工作的变量。
urls.py ----- 负责把URL模式映射到应用程序。
wsgi.py:wsgi是Python语言定义的web服务器和web服务程序或者框架之间的一种简单而通用的接口。

2、创建应用

python manage.py startapp blog

目录结构

3、启动项目

  在settings.py文件中加入blog app

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog', //自己新建的项目
]

 

python manage.py runserver 8080

访问
http://127.0.0.1:8080/

4、配置url

from django.conf.urls import include, url
from blog.views import * // 导入app blog  views.py中所有函数
urlpatterns = [
    path('admin/', admin.site.urls),
    url(r'^userinfo/', userinfo),
]

5、写逻辑处理函数

info_list=[]

def userinfo(request):

    if request.method=="POST":
        username=request.POST.get("username",None)
        sex=request.POST.get("sex",None)
        email=request.POST.get("email",None)

        info={"username":username,"sex":sex,"email":email}
        info_list.append(info)

    return render(request,"info.html",{"info_list":info_list}) //返回info.html  把info_list传到html使模板进行渲染格式:{"info_list":info_list}

 

 6、写html模板

 准备

settings.py文件里设置DIRS

'DIRS': [os.path.join(BASE_DIR, 'templates')],

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同级目录下创建templates目录

编写info.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>创建个人信息</h1>

<form action="/userinfo/" method="post">
    {% csrf_token %}

    <p>姓名<input type="text" name="username"></p>
    <p>性别<input type="text" name="sex"></p>
    <p>邮箱<input type="text" name="email"></p>
    <p><input type="submit" value="提交"></p>

</form>

<hr>

<h1>信息展示</h1>

<table border="1">

    <tr>
        <td>姓名</td>
        <td>性别</td>
        <td>邮箱</td>
    </tr>
    {% for i in info_list %}

        <tr>
            <!--获取字典i中键为username的值-->
            <td>{{ i.username }}</td>
            <td>{{ i.sex }}</td>
            <td>{{ i.email }}</td>
        </tr>

    {% endfor %}

</table>

</body>
</html>
info.html

 

7、测试

 8、数据信息存储在数据库

      上面的数据在django重启后就没了,要想使数据永久保存,需把数据放在数据库中

     vim models.py 

from django.db import models

# Create your models here.

class UserInfor(models.Model):

    username=models.CharField(max_length=64)
    sex=models.CharField(max_length=64)
    email=models.CharField(max_length=64)
$ python manage.py makemigrations
Migrations for 'blog':
  blog\migrations\0001_initial.py
    - Create model UserInfor




$python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, blog, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying blog.0001_initial... OK
  Applying sessions.0001_initial... OK
同步数据到数据库

   vim views.py

from django.shortcuts import render
from blog.models import *
# Create your views here.

# info_list=[]
#
# def userinfo(request):
#
#     if request.method=="POST":
#         username=request.POST.get("username",None)
#         sex=request.POST.get("sex",None)
#         email=request.POST.get("email",None)
#
#         info={"username":username,"sex":sex,"email":email}
#         info_list.append(info)
#
#
#     return render(request,"info.html",{"info_list":info_list})


def userinfo(request):

    if request.method=="POST":
        u=request.POST.get("username",None)
        s=request.POST.get("sex",None)
        e=request.POST.get("email",None)
        #把获取到数据写入数据库
        #info = {"username": u, "sex": e, "email": e}
        #UserInfor.objects.create(**info)
        #把获取到数据写入数据库
        UserInfor.objects.create(
            username=u,
            sex=s,
            email=e
        )
        info_list = UserInfor.objects.all()
        return render(request, "info.html", {"info_list": info_list}) #是post请求时,把info_list传给info.html 渲染后返回info.html给用户 '信息展示显示数据库中已存的所有数据'
    return render(request,"info.html") #第一次是get请求返回info.html '信息展示那里不显示任何信息'
View Code
三、Django各部分介绍
3.1 URL介绍

     告诉django用户请求的url应该对应哪个视图函数

     3.1.1 url配置格式:
urlpatterns = [
    url(正则表达式, views视图函数,参数,别名),
]


参数说明:
    一个正则表达式字符串
    一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
    可选的要传递给视图函数的默认参数(字典形式)
    一个可选的name参数


例子:url(r'^userinfo/', userinfo),
     url(r'^articles/[0-9]{4}/$', views.year_archive),
      3.1.2 通过url传参数到视图函数

     1、无命名参数

       大括号括()起来的为参数

url配置
url(r'^index/([0-9]{4})/$', index), #no_named group
url(r'^index/([0-9]{4})/([0-9]{2})/$', index),  
 
views代码

def index(request,arg):
    return HttpResponse('hello'+arg)

def index(request,arg1,arg2):
return HttpResponse('hello'+arg1+arg2)

注意:无论前端是数字还是字符串,作为参数传到后端都是以字符串处理
无命名参数,参数传入是有顺序之分的
在浏览器请求http://127.0.0.1/index/2019

可以看大浏览器返回:hello2019
在浏览器请求http://127.0.0.1/index/2019/08
可以看到浏览器返回:hello201908
 

    2、有名字参数

     格式:

(?P<name>[0-9]{4})

固定格式:(?P<>)
name:参数名字
[0-9]{4}正则表达式

 

url 配置

url(r'^index/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', index),


year和month分别是参数的名字
def index(request,year,month):
    return HttpResponse('hello'+year+month)



注意:year和month必须和url中名字保持一致
         year和month没有固定顺序,按照对应的名字获取参数的值

 

    3.1.3 url别名使用

    格式:

url(r'^login/', login,name='loginname'),
name是固定的,loginname是login别名
def login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'root' and password == '123':
            return HttpResponse("登陆成功")

    return render(request, 'login.html')
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
{#     <form action="/index/" method="post">#}
     <form action="{% url 'loginname' %}" method="post">
         <!--渲染的时候django会去urls.py中找name='loginname'的url,然后替换-->
          {% csrf_token %}
         用户名:<input type="text" name="username">
         密码:<input type="password" name="password">
         <input type="submit" value="submit">
     </form>
</body>
</html>
login.html
    3.1.4 url映射分发

    Django中有很多不同的app,要想实现其具体的功能,就要用到路径分发。在不同的app中定义自己需要的url

全局urls.py配置


url(r'^blog/', include('blog.urls')), #一旦浏览器中输入blog,就找到blog中urls.py

app blog 中urls.py配置

from django.urls import path
from . import views

#app_name = 'blog'

urlpatterns = [
    path("login/",views.userinfo),
]
在浏览器中输入:http://127.0.0.1:8080/blog/login 即可看到返回的页面
3.2 视图函数
path: 请求页面的全路径,不包括域名
method:请求中使用的HTTP方法的字符串表示。全大写表示
GET/POST:  包含所有HTTP GET/POST参数的类字典对象
                  可以通过request.POST.get('username')获取对应的值
COOKIES:  包含所有cookies的标准Python字典对象;keys和values都是字符串
FILES:包含所有上传文件的类字典对象;FILES中的每一个Key都是<input type="file" name="" />标签中                     name属性的值,FILES中的每一个value同时也是一个标准的python字典对象,包含下面三个Keys:
        filename:  上传文件名,用字符串表示
        content_type:   上传文件的Content Type
        content:       上传文件的原始内容

request.POST.getlist("hobby"):键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用
HttpRequest对象的属性和方法

    HttpResponse对象

    对于HttpRequest对象来说,是由django自动创建的,但是,HttpResponse对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse对象

 

1.render 函数
    将指定页面渲染后返回给浏览器
格式:render(request, template_name[, context])
参数说明:
    request: 用于生成响应的请求对象
    template_name:要使用的模板的完整名称,可选的参数
    context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它
    content_type:生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。


render方法主要是将从服务器提取的数据,填充到模板中,然后将渲染后的html静态文件返回给浏览器。这里一定要注意:render渲染的是模板

例子:
return render(request, "info.html")
return render(request, "info.html", {"info": info_list})  #info_list可以是字符串、列表、字典


   herolist = book.heroinfo_set.all()  
    context = {'list': herolist}       # 将数据保存在list
    return render(request, 'booktest/show.html', context) #通过render进行模板渲染
render 函数
redirect :页面跳转,一般会生成一个302状态码

return rediect('/login.html/')
return rediect('/http://www.baidu.com/')



return render(request,'login.html')只是跳到login.html这个页面上去,没有别的任何操作
return rediect('/login.html/') 执行的的是url里面的函数,相当于又一次调用新的函数,/login.html/函数里面的所有代码都会执行,
locals()返回一个包含当前作用域里面的所有变量和它们的值的字典。


def index(request):
  username='root'
  return render(request, 'login.html',locals())



在模板中可以直接使用name获取对应值

<p>姓名:{{ username }}</p>
 3.3模板 Template

    模板由"HTML代码+逻辑控制代码"组成

    Django模板中只需要记两种特殊符号:{{  }}和{% %}, 其中{{  }}表示变量,在模板渲染的时候替换成值,{% %}表示逻辑相关的操作

    3、1 变量(使用双大括号来引用变量)

语法格式:       {{var_name}}

    变量名由字母数字和下划线组成,点(.)在模板语言中有特殊的含义,用来获取对象的相应属性值。

     模板中支持的写法:
{# 访问列表索引,取列表l中的索引为0是数据 #}
{{ l.0 }}
{# 取字典中key的值 #}
{{ d.name }}
{# 取对象的name属性 可以是python内置的对象或者是自定义类中对象的属性#}
{{ person_list.0.name }}
{# 点语法也可以用来引用对象的方法  但是.操作只能调用不带参数的方法 #}
{{ person_list.0.dream }}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3>变量练习</h3>
<p> 字符串:{{ s }}</p>
<p> 列表:{{ l }}</p>
<p> 列表索引:{{ l.0 }}</p>
<p> 字典:{{ dic.name }} </p>
<p> 自定义类:姓名:{{ person.name }}年龄:{{ person.age }}</p>
</body>
</html>
变量列子html
def index(request):
    s='aaaaaaaaaaa'
    l=['a','b','c']
    dic={'name':'yqh'}
    class People:
        def __init__(self,name,age):
            self.name=name
            self.age=age

    person=People('yqh',18)
    return render(request,"index.html",{'s':s,'l':l,'dic':dic,'person':person})
变量例子views.py

     3、2 标签tag

    标签语法是:{% tag %},它比变量更加复杂:一些在输出中创建文本,一些通过循环或者逻辑来控制流程,一些加载其后的变量将使用道德额外信息到模板中。一些标签需要开始和结束标签(例如:{% tag %}... 标签内容...{% endtag %})。

        1、for标签语法如下:

{%for item in 列表%}
循环逻辑
{{forloop.counter}}表示当前是第几次循环,从1开始
{%empty%}
列表为空或不存在时执行此逻辑
{%endfor%}
   Variable                       Description
forloop.counter            当前循环的索引值(从1开始)
forloop.counter0    当前循环的索引值(从0开始)
forloop.revcounter    当前循环的倒序索引值(到1结束)
forloop.revcounter0    当前循环的倒序索引值(到0结束)
forloop.first            当前循环是不是第一次循环(布尔值)
forloop.last            当前循环是不是最后一次循环(布尔值)
forloop.parentloop    本层循环的外层循环
for循环可用的一些参数

        2、if标签语法如下:

 

{%if ...%}
逻辑1
{%elif ...%}
逻辑2
{%else%}
逻辑3
{%endif%}
{% if %}标签计算一个变量值,如果是“true”,即它存在、不为空并且不是false的boolean值,系统则会显示{% if %}和{% endif %}间的所有内容
   
支持的操作符有 not,and,or,==, !=, <, >, <=, >=, in, not in, is, is not
注意:运算符左右两侧不能紧挨变量或常量,必须有空格。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--<h3>变量练习</h3>-->
<!--<p> 字符串:{{ s }}</p>-->
<!--<p> 列表:{{ l }}</p>-->
<!--<p> 列表索引:{{ l.0 }}</p>-->
<!--<p> 字典:{{ dic.name }} </p>-->
<!--<p> 自定义类:姓名:{{ person.name }}年龄:{{ person.age }}</p>-->



<ul>
    {% for book in dic %}
        {% if book.id == 1 %}
            <li style="background-color: red;">{{book.btitle}}</li>

       {% elif book.id == 2 %}
            <li style="background-color: blue;">{{book.btitle}}</li>
       {% else %}
            <li style="background-color: green;">{{book.btitle}}</li>
       {%endif%}
    {%empty%}
        <li>对不起没数据</li>
    {% endfor %}
</ul>
</body>
</html>
html代码
def index(request):

    l=[]

    class Book:
        def __init__(self,id,btitle):
            self.id=id
            self.btitle=btitle

    book1 = Book(1,'python')
    book2 = Book(2, 'java')
    book3 = Book(3, 'shell')
    l.append(book1)
    l.append(book2)
    l.append(book3)

    return render(request,"index.html",{'dic':l})
views部分代码

    访问:http://127.0.0.1:8080/index

 

     当传入html数据为空时

 

       3、with标签

    使用一个简单的名字还出一个复杂的变量,当我们需要一个"昂贵的"方法(比如:访问数据库)很多次的时候是非常有用的

{% with total=fhjsaldfhjsdfhlasdfhljsdal %} 
   {{ total }} 
{% endwith %}

        4、csrf_token标签

    提交数据的时候会做安全机制,当用户点击提交的时候会出现一个forbidden错误,就是用settings配置里面的csrf做的安全机制,如果我们不需要使用,可以将其注释。或者在form表单下面添加{% csrf_token %}来解决该问题(这才是真正的解决办法,注释不是解决办法)。

<form action="/tag/" method="post">
        {% csrf_token %}
        <p><input type="text" name="test"></p>
        <input type="submit">
    </form>
View Code

        5、{% url %}:  引用路由配置的地址

        6、{% verbatim %}: 禁止render

{% verbatim %}
         {{ hello }}
{% endverbatim %}



不把hello当做变量,原样显示 {{ hello }}

     3、3 过滤器

    过滤器会更改变量或标签参数的值,可以通过使用 过滤器来改变变量的显示;使用管道符号 (|)来应用过滤器;过滤器可以“链接”,即一个过滤器的输出应用于下一个过滤器

语法:
变量|过滤器:参数

1、使用管道符号|来应用过滤器,用于进行计算、转换操作,可以使用在变量、标签中。
2、如果过滤器需要参数,则使用冒号:传递参数
常见过滤器

1.default:{{ variable| default: "nothing"}},如果变量是false或者为空,使用默认值。否则,使用变量的值
    <p>default过滤器:{{ li|default:"如果显示为空,设置解释性的内容。" }}</p>
2、length:返回值的长度,它对字符串和列表都起作用
    {{ value | length }}        # 如果value是["a", "b", "c", "d"],那么输出是4
3、date:格式化日期时间格式
    {{ value | date:"Y-m-d" }}        # 如果value=datetime.datetime.now(),返回时间的年-月-日格式
4、safe
    django的模板中会对HTML标签和JS语法标签进行自动转义,这样是为了安全。但是有的时候我们不想这些HTML元素被转义,比如我们做一个内容管理系统,后台添加的文章是经过修饰的,这些修饰可能是通过类似于FCKeditor编辑加注了HTML修饰符的文本,如果自动转义的话显示的就是保护HTML标签的源文件。为了在django中关闭HTML自动转义有两种方式,如果是一个单独的变量我们可以通过过滤器"|safe"的方式告诉django这段代码是安全的不必转义,如下:
    value="<a href="">点击</a>""
    {{ value | safe }}
<p>{{ label }}</p> # 为了安全,系统会把标签变成字符串 <p>{{ label | safe }}</p> # 加上safe,确定数据时安全的才能被当成是标签

    3、4  自定义标签(tag)和过滤器(filter)

        实现方式

        1、在app目录中创建templatetags包(包名只能是templatetags)  

total 17
-rw-r--r-- 1 migu 197121    0 八月 23 14:11 __init__.py
drwxr-xr-x 1 migu 197121    0 八月 29 17:05 __pycache__/
-rw-r--r-- 1 migu 197121   66 八月 23 14:11 admin.py
-rw-r--r-- 1 migu 197121   88 八月 23 14:11 apps.py
drwxr-xr-x 1 migu 197121    0 八月 23 15:25 migrations/
-rw-r--r-- 1 migu 197121  224 八月 23 15:20 models.py
drwxr-xr-x 1 migu 197121    0 八月 29 17:29 templates/
drwxr-xr-x 1 migu 197121    0 八月 30 14:13 templatetags/
-rw-r--r-- 1 migu 197121   63 八月 23 14:11 tests.py
-rw-r--r-- 1 migu 197121  129 八月 26 20:40 urls.py
-rw-r--r-- 1 migu 197121 2028 八月 29 17:05 views.py

        2、在templatetags目录下创建任意的.py文件 如:my_tags.py

$ ll templatetags/
total 0
-rw-r--r-- 1 migu 197121 0 八月 30 14:13 __init__.py
-rw-r--r-- 1 migu 197121 0 八月 30 14:16 my_tags.py

     3、在my_tags.py文件中添加自定义的标签和过滤器

from django import template
from django.utils.safestring import mark_safe

register = template.Library()   #register的名字是固定的,不可改变

#自己定义filter
@register.filter
def myfilter(v1):#无参数
    return  v1+10

@register.filter
def myfilter1(v1,v2):#有参数
    return  v1 + v2

#自己定义tag
@register.simple_tag
def mytag(v1,v2,v3):
    return  v1 + v2+v3

    4、在使用自定义simple_tag和filter的html文件中导入之前创建的 my_tags.py :{% load my_tags %}

{# 先导入我们自定义filter那个文件 必须在首行 #}
{% load my_tags%}


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

{# 使用我们自定义的filter #}
<p>
    <!--过滤器myfilter将传递变量num-->
    数值加10:{{ num|myfilter }}
</p>

<p>
    <!--过滤器myfilter将传递变量num和参数1-->
    数值加传入的值:{{ num|myfilter1:1 }}
</p>

{# 使用我们自定义的tag #}
<p>
    {% mytag 'a' 'b' 'c' %}
</p>

</body>
</html>
url(r'^tag/', mytag),



def mytag(request):
    num=1
    return render(request,'mytag.html',{'num':num})
url和views部分代码
访问:http://127.0.0.1:8080/tag


输出结果:

数值加10:11

数值加传入的值:2

abc
自定义标签:参数不限,但不能放在if for语句中
自定义过滤器:可以放在if for 语句中,最多2个参数
自定义标签和过滤器注意

     3、5模板继承

    模版继承可以让您创建一个基本的“骨架”模版,它包含您站点中的全部元素,并且可以定义能够被子模版覆盖的 blocks 。

父模板:如果发现在多个模板中某些内容相同,那就应该把这段内容定义到父模板中。

标签block:用于在父模板中预留区域,留给子模板填充差异性的内容,名字不能相同。 为了更好的可读性,建议给endblock标签写上名字,这个名字与对应的block名字相同。父模板中也可以使用上下文中传递过来的数据。


{%block 名称%}
预留区域,可以编写默认内容,也可以没有默认内容
{%endblock  名称%}
子模板
标签extends:继承,写在子模板文件的第一行。

{% extends "父模板"%}

子模版不用填充父模版中的所有预留区域,如果子模版没有填充,则使用父模版定义的默认值。


{%block 名称%}
实际填充内容
{{block.super}}用于获取父模板中block的内容
{%endblock 名称%}

    模板继承例子部分代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
         * {
            margin:0;
         }
        .page-header{
            height:30px;
            background-color:rebeccapurple;
        }
        .page-body .menu{
            height:700px;
            background-color:antiquewhite;
            float:left;
            width:20%
        }
        .page-body .content{
           height:700px;
           background-color:cornflowerblue;
           float:left;
           width:80%
         }

        .page-footer{
            height:30px;
            background-color:darkcyan;
            clear:both;
        }
        a {display: block;
        }

    </style>
</head>
<body>

<div>
    <div class="page-header"></div>
    <div class="page-body">
        <div class="menu">
            <a  href="/shouye">首页</a>
            <a  href="/dingdan">订单</a>
        </div>
        <div class="content">
            {% block page-content %}
             默认信息
            {% endblock %}
        </div>

    </div>
    <div class="page-footer"></div>
</div>
</body>
</html>
base.html
{% extends 'base.html' %}

{% block page-content %}
   <p> 个人信息

   </p>
{% endblock %}
shouye.html
{% extends 'base.html' %}


</style>
{% block page-content %}
   <p> 手机</p>
   <p> 电脑</p>
   <p> 平板</p>
{% endblock %}
dingdan.html
url(r'^index/', index),
url(r'^shouye/', shouye),
url(r'^dingdan/', dingdan),
urls.py
def index(request):
    return render(request,"base.html")

def shouye(request):
    return render(request,"shouye.html")

def dingdan(request):
    return render(request,"dingdan.html")
views.py
分别访问:
http://127.0.0.1:8080/index
http://127.0.0.1:8080/shouye
http://127.0.0.1:8080/dingdan

               

 

 

 

转载于:https://www.cnblogs.com/quanloveshui/p/11400202.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值