Django 2.0使用

1. 准备

首先下载安装django

pip3 install django

pycharm可以直接建立django的项目,也可以执行命令

django-admin startproject mysite

这样就建立了一个mysite的django项目。

下面是新建项目的目录文件列表

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

其中,
settings.py是项目各种配置的文件
urls.py是url目录文件
manage.py是管理工具

尝试运行(pycharm可以直接点击Django项目运行)
也可以shell运行命令

python manage.py runserver

运行成功后的输出
Performing system checks...

System check identified no issues (0 silenced).

You have unapplied migrations; your app may not work properly until they are applied.
Run 'python manage.py migrate' to apply them.

六月 01, 2018 - 15:50:53
Django version 2.0, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

2.创建一个应用

python manage.py startapp polls

创建完成后会在mysite目录下看到一个polls文件目录

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

应用创建完成了不过,等下模型的学习中还要使用

3.视图

现在创建我们的第一个视图应用

from django.http import HttpResponse,request
# Create your views here.
def hello(request):
    html = '<html><body>hello world</body></heml>'
    return HttpResponse(html)

同时配置我们的polls/urls.py

添加:
path("",views.hello,name='index')


完成后是这个样子:

from django.urls import path,include

from . import views
urlpatterns =[
    #首页设置
    path("",views.hello,name='index'),
]

这仅仅是polls下的配置,mysite还无法知道这是什么意思,所以我们还要配置mysite/urls.py
打开mysite/urls.py后里面已经有内容了,在其中添加

path('polls/',include('polls.urls')),


配置好以后的样子

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

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

然后就可以打开浏览器输入链接:
http://127.0.0.1:8000/polls/

这里面用到了include
在官方文档中是这样写的:

函数 include() 允许引用其它 URLconfs。每当 Django 遇到 :func:~django.urls.include
时,它会截断与此项匹配的 URL 的部分,并将剩余的字符串发送到 URLconf 以供进一步处理。 我们设计 include()
的理念是使其可以即插即用。因为投票应用有它自己的 URLconf( polls/urls.py ),他们能够被放在 “/polls/” ,
“/fun_polls/” ,”/content/polls/”,或者其他任何路径下,这个应用都能够正常工作。

接下来理解一下path:

def _path(route, view, kwargs=None, name=None, Pattern=None):
    if isinstance(view, (list, tuple)):
        # For include(...) processing.
        pattern = Pattern(route, is_endpoint=False)
        urlconf_module, app_name, namespace = view
        return URLResolver(
            pattern,
            urlconf_module,
            kwargs,
            app_name=app_name,
            namespace=namespace,
        )
    elif callable(view):
        pattern = Pattern(route, name=name, is_endpoint=True)
        return URLPattern(pattern, view, kwargs, name)
    else:
        raise TypeError('view must be a callable or a list/tuple in the case of include().')

这是path的函数,我们可以看到传递进去的参数:

**route:**route 是一个匹配 URL 的准则(类似正则表达式)。当 Django 响应一个请求时,它会从 urlpatterns 的第一项开始,按顺序依次匹配列表中的项,直到找到匹配的项。这些准则不会匹配 GET 和 POST 参数或域名。例如,URLconf 在处理请求 https://www.example.com/myapp/ 时,它会尝试匹配 myapp/ 。处理请求 https://www.example.com/myapp/?page=3 时,也只会尝试匹配 myapp/。
view:当 Django 找到了一个匹配的准则,就会调用这个特定的视图函数,并传入一个 HttpRequest 对象作为第一个参数,被“捕获”的参数以关键字参数的形式传入。
kwargs=None:任意个关键字参数可以作为一个字典传递给目标视图函数
name=None:为你的 URL 取名能使你在 Django 的任意地方唯一地引用它,尤其是在模板中。这个有用的特性允许你只改一个文件就能全局地修改某个 URL 模式。
Pattern=None:官方文档并没有给解释


其中,博主也只知道使用route和view,设置name之后怎么使用name博主也不知道,如果哪位大大翻了博主的牌,望告知


4.数据库配置

python默认使用的是SQLite,但是博主使用的是mysql,所以接下来都是mysql的配置,如果是其他数据库请看官方文档
在此之前,请确认:
1.安装好mysql数据库
2.已经下载好了mysqlclient(pip/pip3 install mysqlclient)
3.设置好时间在mysite/settings.py
TIME_ZONE = ‘Asia/Shanghai’

看到下面的内容, 我们打开mysite/settings.py

sqlite:’django.db.backends.sqlite3’
postgresql:’django.db.backends.postgresql’
mysql:’django.db.backends.mysql‘
oracle:’django.db.backends.oracle’

找到DATABASES这个设置,填写以下内容

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'polls',
        'USER': 'root',
        'PASSWORD': '123456',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

NAME: 数据库名字
USER:用户名
PASSWORD:用户密码
HOST:ip
PORT:端口

在创建自己的模型之前,我们先运行

python manage.py migrate

这是为为我们的admin应用创建数据库表格

接下来编写我们的模型:
打开polls/models.py,填写以下代码:

from django.db import models

# Create your models here.
class Question(models.Model):
    question_text = models.CharField(max_length=200)
    pub_data = 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.modles.Model的子类,每个模型都有一些变量, 这是表示模型里面的数据库的字段
每个字段我们都设置了一个类型, 比如CharField,DateTImeFIeld,用来告诉django处理数据的类型。其中我们定义了一个Field名字,在官方文档中, 他是这样解释的:

你可以使用可选的选项来为 Field 定义一个人类可读的名字。这个功能在很多 Django
内部组成部分中都被使用了,而且作为文档的一部分。如果某个字段没有提供此名称,Django
将会使用对机器友好的名称,也就是变量名。在上面的例子中,我们只为 Question.pub_date
定义了对人类友好的名字。对于模型内的其它字段,它们的机器友好名也会被作为人类友好名使用。

Field中有些参数,例如 max_length 这个浅显易懂,就是长度设置,当然也可以设置默认值,例如 :default = 0
最后我们定义了ForeignKey,这是一对一关系, 告诉我们每个choice都对应了一个question,后面的参数是:
models.CASCADE:对就对象删除后,包含ForeignKey的字段也会被删除
models.PROTECT:删除时会引起ProtectedError
models.SET_NULL:注意只有当当前字段设置null设置为True才有效,此情况会将ForeignKey字段设置为null
models.SET_DEFAULT :同样,当前字段设置了default才有效,此情况会将ForeignKey 字段设置为default 值
moels.SET:此时需要指定set的值
models.DO_NOTHING :什么也不做

写好模型之后我们要去激活我们的模型,在mysite/settings.py中找到这个INSTALLED_APPS
在里面添加

#因为PollsConfig类写在了polls/apps中
’polls.apps.PollsConfig

接着,我们运行以下命令:

#通过运行 makemigrations 命令,Django 会检测你对模型文件的修改(在这种情况下,你已经取得了新的),并且把修改的部分储存为一次 迁移。
python manage.py makemigrations polls

#输出
Migrations for 'polls':
  polls/migrations/0001_initial.py:
    - Create model Choice
    - Create model Question
    - Add field question to choice


#查看迁移执行的命令
python manage.py sqlmigrate polls 0001
#输出
BEGIN;
--
-- Create model Choice
--
CREATE TABLE `polls_choice` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `choice_text` varchar(200) NOT NULL, `votes` integer NOT NULL);
--
-- Create model Question
--
CREATE TABLE `polls_question` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `question_text` varchar(200) NOT NULL, `pub_data` datetime(6) NOT NULL);
--
-- Add field question to choice
--
ALTER TABLE `polls_choice` ADD COLUMN `question_id` integer NOT NULL;
ALTER TABLE `polls_choice` ADD CONSTRAINT `polls_choice_question_id_c5b4b260_fk_polls_question_id` FOREIGN KEY (`question_id`) REFERENCES `polls_question` (`id`);
COMMIT;

关于迁移和官方文档的提醒要点:

1、迁移是 Django 对于模型定义(也就是你的数据库结构)的变化的储存形式 - 没那么玄乎,它们其实也只是一些你磁盘上的文件。如果你想的话,你可以阅读一下你模型的迁移数据,它被储存在 polls/migrations/0001_initial.py 里。别担心,你不需要每次都阅读迁移文件,但是它们被设计成人类可读的形式,这是为了便于你手动修改它们。

2、注意要点:

  • 输出的内容和你使用的数据库有关,上面的输出示例使用的是 PostgreSQL。
  • 数据库的表名是由应用名(polls)和模型名的小写形式( question 和 choice)连接而来。(如果需要,你可以自定义此行为。)
  • 主键(IDs)会被自动创建。(当然,你也可以自定义。)
  • 默认的,Django 会在外键字段名后追加字符串 “_id” 。(同样,这也可以自定义。)
  • 外键关系由 FOREIGN KEY 生成。你不用关心 DEFERRABLE 部分,它只是告诉 PostgreSQL,请在事务全都执行完之后再创建外键关系。
  • 生成的 SQL 语句是为你所用的数据库定制的,所以那些和数据库有关的字段类型,比如 auto_increment (MySQL)、 serial (PostgreSQL)和 integer primary key autoincrement (SQLite),Django 会帮你自动处理。那些和引号相关的事情 - 例如,是使用单引号还是双引号 - 也一样会被自动处理。
  • 这个 sqlmigrate 命令并没有真正在你的数据库中的执行迁移 - 它只是把命令输出到屏幕上,让你看看 Django 认为需要执行哪些 SQL 语句。这在你想看看 Django 到底准备做什么,或者当你是数据库管理员,需要写脚本来批量处理数据库时会很有用。

再次执行命令:

python manage.py migrate

#输出
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Rendering model states... DONE
  Applying polls.0001_initial... OK

这样,数据库中就自动创建了表格

总结:

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

  • 运行 python manage.py makemigrations 为模型的改变生成迁移文件。

  • 运行 python manage.py migrate 来应用数据库迁移。

5.API使用

*此段直接引用于官方文档

$ python manage.py shell
>>> from polls.models import Choice, Question  # Import the model classes we just wrote.

# No questions are in the system yet.
>>> Question.objects.all()
<QuerySet []>

# Create a new Question.
# Support for time zones is enabled in the default settings file, so
# Django expects a datetime with tzinfo for pub_date. Use timezone.now()
# instead of datetime.datetime.now() and it will do the right thing.
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())

# Save the object into the database. You have to call save() explicitly.
>>> q.save()

# Now it has an ID.
>>> q.id
1

# Access model field values via Python attributes.
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)

# Change values by changing the attributes, then calling save().
>>> q.question_text = "What's up?"
>>> q.save()

# objects.all() displays all the questions in the database.
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>

Question object(1)对于我们了解这个对象的细节没什么帮助。让我们通过编辑 Question 模型的代码(位于 polls/models.py 中)来修复这个问题。给 Question 和 Choice 增加 str() 方法。
polls/models.py

from django.db import models

class Question(models.Model):
    # ...
    def __str__(self):
        return self.question_text

class Choice(models.Model):
    # ...
    def __str__(self):
        return self.choice_text

给模型增加 str() 方法是很重要的,这不仅仅能给你在命令行里使用带来方便,Django 自动生成的 admin 里也使用这个方法来表示对象。

注意:这些都是常规的 Python方法。让我们添加一个自定义的方法,这只是为了演示:
polls/models.py

import datetime

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


class Question(models.Model):
    # ...
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1)

新加入的 import datetime 和 from django.utils import timezone 分别导入了 Python 的标准 datetime 模块和 Django 中和时区相关的 django.utils.timezone 工具模块。如果你不太熟悉 Python 中的时区处理,看看 时区支持文档 吧。

保存文件然后通过 python manage.py shell 命令再次打开 Python 交互式命令行:


>>> from polls.models import Choice, Question

# Make sure our __str__() addition worked.
>>> Question.objects.all()
<QuerySet [<Question: What's up?>]>

# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: What's up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: What's up?>]>

# Get the question that was published this year.
>>> from django.utils import timezone
>>> current_year = timezone.now().year
>>> Question.objects.get(pub_date__year=current_year)
<Question: What's up?>

# Request an ID that doesn't exist, this will raise an exception.
>>> Question.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Question matching query does not exist.

# Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups.
# The following is identical to Question.objects.get(id=1).
>>> Question.objects.get(pk=1)
<Question: What's up?>

# Make sure our custom method worked.
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True

# Give the Question a couple of Choices. The create call constructs a new
# Choice object, does the INSERT statement, adds the choice to the set
# of available choices and returns the new Choice object. Django creates
# a set to hold the "other side" of a ForeignKey relation
# (e.g. a question's choice) which can be accessed via the API.
>>> q = Question.objects.get(pk=1)

# Display any choices from the related object set -- none so far.
>>> q.choice_set.all()
<QuerySet []>

# Create three choices.
>>> 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)

# Choice objects have API access to their related Question objects.
>>> c.question
<Question: What's up?>

# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> q.choice_set.count()
3

# The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships.
# This works as many levels deep as you want; there's no limit.
# Find all Choices for any question whose pub_date is in this year
# (reusing the 'current_year' variable we created above).
>>> Choice.objects.filter(question__pub_date__year=current_year)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()

6.Django管理页面

首先创建一个管理员
python manage.py createsuperuser

接下来会让你输入用户名、邮箱、密码、验证密码

完成后启动项目进入http://127.0.0.1:8000/admin/ ,输入你刚刚设置的账户密码
进去后,我们可以通过这个页面进行管理。
如果需要管理,我们要告诉他管理什么东西:
进入polls/admin

from django.contrib import admin

from .models import Question

admin.site.register(Question)

现在可以通过admin管理question的内容

猜你喜欢

转载自blog.csdn.net/King_Giji/article/details/80556418