使用Django2快速开发Web项目的详细步骤


Posted in Python onJanuary 06, 2019

Django 是一款基于 Python 编写并且采用 MVC 设计模式的开源的 Web 应用框架,早期是作为劳伦斯出版集团新闻网站的 CMS 内容管理系统而开发,后于 2005 年 7 月在 BSD 许可协议下开源,并于 2017 年 12 月 2 日 发布 2.0 正式版。

使用Django2快速开发Web项目的详细步骤

本文基于《Django 官方 Tutorials》以及《Django REST framework 官方 Tutorials》编写,发稿时所使用的 Django 版本为 2.1.4,Python 版本为 3.6.6,文中涉及的代码都已经由笔者验证运行通过,最终形成了一个简单项目并推送至笔者Github上的jungle项目当中,需要的朋友可以基于此来逐步步完善成为一个产品化的项目。

新建 Django 项目

下面的命令行展示了在 Windows 操作系统下,基于 venv 虚拟环境搭建一个 Django 项目的步骤:

# 建立虚拟环境
C:\Workspace\django
λ python -m venv venv

# 激活虚拟环境
C:\Workspace\django
λ .\venv\Scripts\activate.bat
(venv) λ

# 安装Django
C:\Workspace\django
(venv) λ pip install Django
Looking in indexes: https://mirrors.aliyun.com/pypi/simple/
Collecting Django
 Using cached https://mirrors.aliyun.com/pypi/packages/fd/9a/0c028ea0fe4f5803dda1a7afabeed958d0c8b79b0fe762ffbf728db3b90d/Django-2.1.4-py3-none-any.whl
Collecting pytz (from Django)
 Using cached https://mirrors.aliyun.com/pypi/packages/f8/0e/2365ddc010afb3d79147f1dd544e5ee24bf4ece58ab99b16fbb465ce6dc0/pytz-2018.7-py2.py3-none-any.whl
Installing collected packages: pytz, Django
Successfully installed Django-2.1.4 pytz-2018.7

# 进入虚拟环境目录,新建一个Django项目
C:\Workspace\django
(venv) λ django-admin startproject mysite

C:\Workspace\django
(venv) λ ls
mysite/ venv/

# 进入新建的Django项目,建立一个应用
C:\Workspace\django
(venv) λ cd mysite\

C:\Workspace\django\mysite
(venv) λ python manage.py startapp demo

C:\Workspace\django\mysite
(venv) λ ls
demo/ manage.py* mysite/

# 同步数据库
C:\Workspace\django\mysite
(venv) λ python manage.py migrate
Operations to perform:
 Apply all migrations: admin, auth, 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 sessions.0001_initial... OK

# 启动开发服务
(venv) λ python manage.py runserver 8080
Performing system checks...

System check identified no issues (0 silenced).
January 03, 2019 - 21:31:48
Django version 2.1.4, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8080/
Quit the server with CTRL-BREAK.


# 返回uinika虚拟环境目录,并将当前虚拟环境的依赖导入至requirements.txt
C:\Workspace\django\mysite
(venv) λ cd ..

C:\Workspace\django
(venv) λ pip freeze > requirements.txt

C:\Workspace\django
(venv) λ ls
mysite/ requirements.txt venv/

通过 django-admin startproject 命令创建的外部 mysite/ 目录是 Web 项目的容器,而 manage.py 文件是用于与 Django 项目交互的命令行工具,更多的使用方式可以参阅 django-admin 文档 。。

mysite/
 manage.py
 mysite/
  __init__.py
  settings.py
  urls.py
  wsgi.py

内部嵌套的 mysite/ 目录是用于放置项目中具体的 Python 包,它的名称是您需要用来导入其中任何内容的 Python 包名称,例如 mysite.urls

  • mysite/__init__.py : 空文件,用于提示系统将当前目录识别为一个 Python 包。
  • mysite/settings.py : Django 项目的配置文件,更多配置请查阅 Django settings 。
  • mysite/urls.py : 当前 Django 项目的 URL 声明,更多内容请参阅 URL dispatcher 。
  • mysite/wsgi.py : 兼容 WSGI 规范的当前项目入口点,更多细节可以阅读 如果使用 WSGI 进行部署 。

建立 mysite 项目之后,上面的命令行还通过了 py manage.py startapp 建立了一个 demo/ 应用目录,Django 当中一个项目( mysite )可以拥有多个应用( demo ), demo/ 目录下的文件结构如下:

demo/
 __init__.py
 admin.py
 apps.py
 migrations/
  __init__.py
 models.py
 tests.py
 views.py

请求与响应

首先进入 Python 虚拟环境并进入 mysite 目录后,执行如下命令:

C:\Workspace\django\mysite (master -> origin)
(venv) λ python manage.py startapp polls

新建一个 polls 应用之后,打开该目录下的 polls/views.py 源码文件,输入以下代码:

from django.http import HttpResponse

def index(request):
  return HttpResponse("你好,这是一个投票应用!")

接下来,我们需要将上面修改的视图文件 views.py 映射到一个 URL,先在 polls/ 目录下新建一个 urls.py 文件,然后键入下面这段代码:

from django.urls import path

from . import views

urlpatterns = [
  path('', views.index, name='index'),
]

最后,将上面定义的应用的 URL 声明文件 polls/urls.py 包含至项目的 mysite/urls.py 当中,

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
  path('polls/', include('polls.urls')),
  path('admin/', admin.site.urls),
]

上面代码中出现的 include() 函数主要用于引入其它 URL 配置文件,这样我们就可以通过 http://localhost:8080/polls/ 路径访问到如下信息了:

使用Django2快速开发Web项目的详细步骤

模型和管理页面

mysite/settings.py 文件包含了项目的基本配置,该文件通过如下声明默认使用 Django 内置的 SQLite 作为项目数据库。

DATABASES = {
 'default': {
  'ENGINE': 'django.db.backends.sqlite3',
  'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
 }
}

如果使用其它数据库,则可以将配置书写为下面的格式:

DATABASES = {
 'default': {
  'ENGINE': 'django.db.backends.mysql',  # 数据库引擎名称
  'NAME': 'db',             # 数据库连接名称
  'USER': 'uinika',             # 数据库连接用户名
  'PASSWORD': 'test',         # 数据库连接密码
  'HOST': 'localhost',           # 数据库主机地址
  'PORT': '3306',             # 数据库端口
 }
}

其中 ENGINE 属性可以根据项目所使用数据库的不同而选择如下值:

  • SQLite:django.db.backends.sqlite3
  • MySQL:django.db.backends.mysql
  • PostgreSQL:django.db.backends.postgresql
  • Oracle:django.db.backends.oracle

接下来继续修改 mysite/settings.py ,设置 TIME_ZONE 属性为项目使用国家的时区。

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

mysite/settings.py 文件头部的 INSTALLED_APPS 属性定义了当前项目使用的应用程序。

INSTALLED_APPS = [
 'django.contrib.admin',     # 管理员站点
 'django.contrib.auth',      # 认证授权系统
 'django.contrib.contenttypes',  # 内容类型框架
 'django.contrib.sessions',    # 会话框架
 'django.contrib.messages',    # 消息框架
 'django.contrib.staticfiles',  # 静态文件管理
]

在前面命令行中执行的 python manage.py migrate 命令会检查 INSTALLED_APPS 属性的设置,并为其中的每个应用创建所需的数据表,实际上 migrate 命令只会为对 INSTALLED_APPS 里声明了的应用进行数据库迁移 。

了解项目配置文件的一些设置之后,现在来编辑 polls/models.py 文件新建 Question(问题)Choice(选项) 两个数据模型:

from django.db import models

class Question(models.Model):
  question_text = models.CharField(max_length=200)
  pub_date = models.DateTimeField('date published')

class Choice(models.Model):
  question = models.ForeignKey(Question, on_delete=models.CASCADE)
  choice_text = models.CharField(max_length=200)
  votes = models.IntegerField(default=0)

每个自定义模型都是 django.db.models.Model 的子类,模型里的类变量都表示一个数据库字段,每个字段实质都是 Field 类的实例。注意在 Choice 使用了 ForeignKey 属性定义了一个与 Question 的外键关联关系,Django 支持所有常用的多对一、多对多和一对一数据库关系。

数据库模型建立完成之后,由于 PollsConfig 类位于 polls/apps.py 文件当中,所以其对应的点式路径为 polls.apps.PollsConfig ,现在我们需要将该路径添加至 mysite/settings.py 文件的 INSTALLED_APPS 属性:

INSTALLED_APPS = [
 'polls.apps.PollsConfig', # 添加PollsConfig
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
]

通过 manage.py 提供的 makemigrations 命令,将模型的修改迁移到 SQLite 数据库当中。

C:\Workspace\django\mysite (master -> origin)
(venv) λ python manage.py makemigrations polls
Migrations for 'polls':
 polls\migrations\0001_initial.py
  - Create model Choice
  - Create model Question
  - Add field question to choice

我们还可以通过 manage.py 提供的 sqlmigrate 命令,查看数据迁移过程中执行了哪些 SQL 语句,该命令并不会实质性执行 Django 模型到数据库的迁移任务。

C:\Workspace\django\mysite (master -> origin)
(venv) λ python manage.py sqlmigrate polls 0001
BEGIN;
--
-- Create model Choice
--
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "v
otes" integer NOT NULL);
--
-- Create model Question
--
CREATE TABLE "polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL
, "pub_date" datetime NOT NULL);
--
-- Add field question to choice
--
ALTER TABLE "polls_choice" RENAME TO "polls_choice__old";
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "v
otes" integer NOT NULL, "question_id" integer NOT NULL REFERENCES "polls_question" ("id") DEFERRABLE INITIALLY DEFERR
ED);
INSERT INTO "polls_choice" ("id", "choice_text", "votes", "question_id") SELECT "id", "choice_text", "votes", NULL FR
OM "polls_choice__old";
DROP TABLE "polls_choice__old";
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id");
COMMIT;

Django 模型的数据库主键 ID 会被自动创建, 并会在外键字段名称后追加 _id 字符串作为后缀。

接下来运行 manage.py 提供的 migrate 命令,在根据新定义的模型创建相应的数据库表。

C:\Workspace\django\mysite (master -> origin)
(venv) λ python manage.py migrate
Operations to perform:
 Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
 Applying polls.0001_initial... OK

为了便于在版本管理系统提交迁移数据,Django 将模型的修改分别独立为 生成应用 两个命令,因此修改 Django 模型会涉及如下 3 个步骤:

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

完成上述 Django 模型与数据库的同步之后,接下来可以通过 manage.py 提供的 shell 命令,在命令行工具内运行 Django 提供的交互式 API。

C:\Workspace\django\mysite (master -> origin)
(venv) λ python manage.py shell
Python 3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 03:37:03) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from polls.models import Choice, Question
>>> Question.objects.all()
<QuerySet []>
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save()
>>> q.id
1
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2019, 1, 4, 9, 10, 1, 955820, tzinfo=<UTC>)
>>> q.question_text = "What's up?"
>>> q.save()
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>

上面命令行执行结果中的 <Question: Question object (1)> 对于实际开发没有意义,因此可以考虑为上面建立的 Django 模型增加 __str__() 方法直接打印模型对象的属性数据。为了便于进一步测试,这里还为 Question 类添加一个自定义的 was_published_recently() 方法:

import datetime
from django.db import models
from django.utils import timezone

class Question(models.Model):
  question_text = models.CharField(max_length=200)
  pub_date = models.DateTimeField('date published')
  # 自定义was_published_recently()方法
  def was_published_recently(self):
    return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
  # 添加__str__()方法
  def __str__(self):
    return self.question_text

class Choice(models.Model):
  question = models.ForeignKey(Question, on_delete=models.CASCADE)
  choice_text = models.CharField(max_length=200)
  votes = models.IntegerField(default=0)
  # 添加__str__()方法
  def __str__(self):
    return self.choice_text

完成修改工作之后,再一次运行 python manage.py shell 命令:

C:\Workspace\django\mysite (master -> origin)
(venv) λ python manage.py shell
Python 3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 03:37:03) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from polls.models import Choice, Question
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>
>>> Question.objects.get(id=2)
Traceback (most recent call last):
 File "<console>", line 1, in <module>
 File "C:\Workspace\django\venv\lib\site-packages\django\db\models\manager.py", line 82, in manager_method
  return getattr(self.get_queryset(), name)(*args, **kwargs)
 File "C:\Workspace\django\venv\lib\site-packages\django\db\models\query.py", line 399, in get
  self.model._meta.object_name
polls.models.Question.DoesNotExist: Question matching query does not exist.
>>> Question.objects.get(pk=1)
<Question: What's up?>
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
>>> q = Question.objects.get(pk=1)
>>> q.choice_set.all()
<QuerySet []>
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
>>> c.question
<Question: What's up?>
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
(1, {'polls.Choice': 1})

管理站点

Django 能够根据模型自动创建后台管理界面, 这里我们执行 manage.py 提供的 createsuperuser 命令创建一个管理用户:

C:\Workspace\django\mysite (master -> origin)
(venv) λ python manage.py createsuperuser
Username (leave blank to use 'zhenghang'): hank
Email address: uinika@outlook.com
Password: ********
Password (again): ********
Superuser created successfully.

启动 Django 服务之后,就可以通过 URL 地址 http://localhost:8080/admin/login 并使用上面新建的用户名和密码进行登陆管理操作:

使用Django2快速开发Web项目的详细步骤

登陆后默认只能对权限相关的 UserGroup 进行管理,如果我们需要将 Question 数据模型纳入管理,那么必须要在 polls/admin.py 文件对其进行注册。

from django.contrib import admin
from .models import Question

admin.site.register(Question)

完成注册之后,刷新管理站点页面即可查看到 Question 管理选项:

使用Django2快速开发Web项目的详细步骤

视图与模板

Django 使用 URLconfs 配置将 URL 与视图关联,即将 URL 映射至视图,下面我们将向 polls/views.py 文件添加一些能够接收参数的视图:

from django.http import HttpResponse

def index(request):
  return HttpResponse("你好,这是一个投票应用!")

def detail(request, question_id):
  return HttpResponse("你正在查看问题 %s 。" % question_id)

def results(request, question_id):
  response = "你看到的是问题 %s 的结果。"
  return HttpResponse(response % question_id)

def vote(request, question_id):
  return HttpResponse("你正在对问题 %s 进行投票。" % question_id)

然后将这些新的视图添加至 polls.urls 模块:

from django.urls import path
from . import views

urlpatterns = [
  # 访问 http://localhost:8080/polls/
  path('', views.index, name='index'),
  # 访问 http://localhost:8080/polls/5/
  path('<int:question_id>/', views.detail, name='detail'),
  # 访问 http://localhost:8080/polls/5/results/
  path('<int:question_id>/results/', views.results, name='results'),
  # 访问 http://localhost:8080/polls/5/vote/
  path('<int:question_id>/vote/', views.vote, name='vote'),
]

Django 的每个视图只会完成两个任务:第 1 是返回一个包含被请求页面内容的 HttpResponse 对象,或者抛出一个 Http404 这样的异常。这里为了展示数据库里按照发布日期排序的最近五个投票问题,我们再向 polls/views.py 代码文件的 index() 函数添加如下内容:

from .models import Question

def index(request):
  latest_question_list = Question.objects.order_by('-pub_date')[:5]
  output = ', '.join([q.question_text for q in latest_question_list])
  return HttpResponse(output)

这样直接将数据库查询结果输出到页面的方式并不优雅,实际开发环境当中我们通常会使用模板页面来展示数据,首先在 polls 应用目录下创建一个用来存放模板文件的 templates 目录。由于站点配置文件 mysite/settings.pyTEMPLATES 属性的默认设置,能够让 Django 在每个 INSTALLED_APPS 文件夹中自动寻找 templates 子目录,从而正确定位出模板的位置。

TEMPLATES = [
  {
    'BACKEND': 'django.template.backends.django.DjangoTemplates',
    'DIRS': [],
    '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',
      ],
    },
  },
]

接下来继续在 templates 下面新建一个 polls 目录,然后在里边放置一个 index.html 文件,此时通过 URL 地址 http://localhost:8080/polls/ 就可以访问到这个模板文件,模板文件会将按照发布日期排序了的 Question 列表 latest_question_list 放置到 HttpResponse 上下文,并在 polls/index.html 模板当中完成数据绑定。

from django.http import HttpResponse
from django.template import loader
from .models import Question

def index(request):
  latest_question_list = Question.objects.order_by('-pub_date')[:5]
  template = loader.get_template('polls/index.html')
  context = {
    'latest_question_list': latest_question_list,
  }
  return HttpResponse(template.render(context, request))

事实上,通过使用 render() 方法,Django 能够以更加简化的方式完成载入模板、填充上下文、返回 HttpResponse 对象这一系列步骤:

from django.shortcuts import render
from .models import Question

def index(request):
  latest_question_list = Question.objects.order_by('-pub_date')[:5]
  context = {'latest_question_list': latest_question_list}
  return render(request, 'polls/index.html', context)

接下来处理投票详情页面,这里会有一个新原则,即如果指定 ID 所对应的 Question 不存在,那么视图就会抛出一个 Http404 异常。在 polls/views.py 添加如下代码,

from django.http import Http404
from django.shortcuts import render
from .models import Question

def detail(request, question_id):
  try:
    question = Question.objects.get(pk=question_id)
  except Question.DoesNotExist:
    raise Http404("问题不存在!")
  return render(request, 'polls/detail.html', {'question': qu

然后暂时向 polls/templates/polls/detail.html 添加一行简单的 代码便于测试上面的代码。

Django 提供了诸如 get_object_or_404()get_list_or_404() 这样的快捷函数语法糖来解决 Http404 判断的问题,因而上一步的代码依然可以进一步简化为下面这样:

from django.shortcuts import get_object_or_404, render
from .models import Question

def detail(request, question_id):
  question = get_object_or_404(Question, pk=question_id)
  return render(request, 'polls/detail.html', {'question': question})

让我们进一步完善polls/templates/polls/detail.html,填充完整的视图代码:

<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}
<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>

通过在模板代码中使用.符号来访问变量属性,例如对于上面代码中的, Django 首先会尝试对question对象使用字典查找(既obj.get(str)),如果失败再尝试属性查找(既obj.str),如果依然失败就会尝试列表查找(即obj[int])。另外循环for中的question.choice_set.all语句会被解析为question.choice_set.all()的 Python 的函数调用,完成后将返回一个可迭代的Choice对象,该对象仅限于for循环标签内部使用。

在polls/templates/polls/index.html编写的投票链接里使用了诸如<a href="/polls//" rel="external nofollow" ></a>这样的硬编码,但是这样容易造成视图与后端业务的耦合,因此 Django 提供了url标签来解决这个问题。

<a href="{% url 'detail' question.id %}" rel="external nofollow" >{{ question.question_text }}</a>

实际上在mysite/polls/urls.py内的函数调用path('<int:question_id>/', views.detail, name='detail')当中,path()的name属性就是作用于url标签中的这个特性的。

为了避免项目当中各种应用的 URL 重名,避免url标签被使用时产生歧义,需要在polls/urls.py上添加应用的命名空间作为区分。

from django.urls import path
from . import views

app_name = 'polls'
urlpatterns = [
path('', views.index, name='index'),
path('<int:question_id>/', views.detail, name='detail'),
path('<int:question_id>/results/', views.results, name='results'),
path('<int:question_id>/vote/', views.vote, name='vote'),
]

然后编辑polls/templates/polls/index.html文件,为每个url标签添加上面声明的polls:命名空间。

<li><a href="{% url 'polls:detail' question.id %}" rel="external nofollow" >{{ question.question_text }}</a></li>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python操作日期和时间的方法
Mar 11 Python
在Python的Flask框架中使用模版的入门教程
Apr 20 Python
在Django中编写模版节点及注册标签的方法
Jul 20 Python
python3使用flask编写注册post接口的方法
Dec 28 Python
python 图像平移和旋转的实例
Jan 10 Python
python实现图片中文字分割效果
Jul 22 Python
Python爬虫 bilibili视频弹幕提取过程详解
Jul 31 Python
python不相等的两个字符串的 if 条件判断为True详解
Mar 12 Python
jupyter notebook 多环境conda kernel配置方式
Apr 10 Python
使用PyQt的QLabel组件实现选定目标框功能的方法示例
May 19 Python
浅谈pytorch 模型 .pt, .pth, .pkl的区别及模型保存方式
May 25 Python
python利用opencv实现颜色检测
Feb 23 Python
利用Django提供的ModelForm增删改数据的方法
Jan 06 #Python
Python面向对象类编写细节分析【类,方法,继承,超类,接口等】
Jan 05 #Python
Python面向对象程序设计OOP深入分析【构造函数,组合类,工具类等】
Jan 05 #Python
Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】
Jan 05 #Python
Python3爬虫全国地址信息
Jan 05 #Python
Python图像处理之图像的读取、显示与保存操作【测试可用】
Jan 04 #Python
Python图像处理之图像的缩放、旋转与翻转实现方法示例
Jan 04 #Python
You might like
PHP实现查询手机归属地的方法详解
2017/04/28 PHP
PHP pthreads v3下的Volatile简介与使用方法示例
2020/02/21 PHP
PHP项目多语言配置平台实现过程解析
2020/05/18 PHP
jQuery+CSS 实现随滚动条增减的汽水瓶中的液体效果
2011/09/26 Javascript
使用jquery自定义鼠标样式满足个性需求
2013/11/05 Javascript
Jquery结合HTML5实现文件上传
2015/06/25 Javascript
javascript中的previousSibling和nextSibling的正确用法
2015/09/16 Javascript
JS+CSS实现分类动态选择及移动功能效果代码
2015/10/19 Javascript
JQuery插件Marquee.js实现无缝滚动效果
2016/04/26 Javascript
JavaScript登录验证码的实现
2016/10/27 Javascript
jQuery图片轮播功能实例代码
2017/01/29 Javascript
vuejs绑定class和style样式
2017/04/11 Javascript
jQuery+SpringMVC中的复选框选择与传值实例
2018/01/08 jQuery
解决vue热替换失效的根本原因
2018/09/19 Javascript
JavaScript中常用的简洁高级技巧总结
2019/03/10 Javascript
深入理解Vue keep-alive及实践总结
2019/08/21 Javascript
js canvas实现星空连线背景特效
2019/11/01 Javascript
ES2020 已定稿,真实场景案例分析
2020/05/25 Javascript
[02:25]DOTA2英雄基础教程 熊战士
2014/01/03 DOTA
[36:17]DOTA2上海特级锦标赛 - VGL音乐会全集
2016/03/06 DOTA
Python实现的一个简单LRU cache
2014/09/26 Python
Linux下python与C++使用dlib实现人脸检测
2018/06/29 Python
对Python 两大环境管理神器 pyenv 和 virtualenv详解
2018/12/31 Python
python如何读取bin文件并下发串口
2019/07/05 Python
django重新生成数据库中的某张表方法
2019/08/28 Python
python学生信息管理系统实现代码
2019/12/17 Python
python上传时包含boundary时的解决方法
2020/04/08 Python
HTML5实现自带进度条和滑块滑杆效果
2018/04/17 HTML / CSS
ONLY德国官方在线商店:购买时尚女装
2017/09/21 全球购物
美国50岁以上单身人士约会平台:SilverSingles
2018/06/29 全球购物
Pedro官网:新加坡时尚品牌
2019/08/27 全球购物
大一自我鉴定范文
2013/12/27 职场文书
培训学校2015年度工作总结
2015/07/20 职场文书
医院岗前培训心得体会
2016/01/08 职场文书
Nginx配置https原理及实现过程详解
2021/03/31 Servers
PHP 对接美团大众点评团购券(门票)的开发步骤
2021/04/03 PHP