Django-01 Start

作者: 霡霂976447044 | 来源:发表于2019-03-31 16:51 被阅读2次

0 环境

再次重新过一下Django的知识。
开发环境,Linux Mint 19。
IDE, PyCharm, Vim
Python: 3
Django: 2.1.7

1 Start

这里直接使用Pycharm了,创建一个新的Project。

 pip install django -i https://pypi.douban.com/simple --trusted-host=pypi.douban.com

1.1 创建Django Project

django-admin startproject HelloWorldPro
~/PycharmProjects/django-study » tree HelloWorldPro                                                                                                                               alonebo@alonebo-pc
HelloWorldPro
├── HelloWorldPro
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

1 directory, 5 files

可以看到创建了一个同名的子目录,外层目录同级还有一个manage.py
settings.py: 项目的配置文件。
urls.py: 进行url路由的配置。
wsgi.py: web服务器和Django交互的入口。

1.2 创建appilcation

切换cmd工作目录为HelloWorldPro
app相当于django项目对每一个业务逻辑模块的细分。
切换工作目录为HelloWorldPro。

django-admin startapp helloapp
~/PycharmProjects/django-study/HelloWorldPro » tree                                                                                                                               alonebo@alonebo-pc
.
├── helloapp
│   ├── admin.py
│   ├── apps.py
│   ├── __init__.py
│   ├── migrations
│   │   └── __init__.py
│   ├── models.py
│   ├── tests.py
│   └── views.py
├── HelloWorldPro
│   ├── __init__.py
│   ├── __pycache__
│   │   ├── __init__.cpython-36.pyc
│   │   └── settings.cpython-36.pyc
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py

4 directories, 14 files

在helloapp目录里面,相关介绍如下
models.py: 写和数据库项目的内容, 设计模型类。
views.py: 接收请求,进行处理,与M和T进行交互,返回应答。定义处理函数,视图函数。
tests.py: 写测试代码的文件。
admin.py: 网站后台管理相关的文件。

1.3 注册创建的app

HelloWorldPro>> vim HelloWorldPro/settings.py

%s/staticfiles',/staticfiles',\r    'helloapp' 

在INSTALLED_APPS 列表里面添加。

1.4 Runserver

之前说过,项目顶层目录有一个manage.py,现在,它就派上用处了。

python manager.py runserver

测试是否正常

firefox localhost:8000

1.5 HelloWorld

为了访问能够展示Hello World,我们需要创建视图,修改路由信息
修改HelloWorldPro/helloapp/views.py

from django.shortcuts import HttpResponse


def hello(request):
    return HttpResponse("Hello Baloneo")

修改HelloWorldPro/HelloWorldPro/urls.py

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

from helloapp.views import hello as hello_view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', hello_view)
]

测试是否成功

curl localhost:8000/hello

PyCharm提示找不到helloapp,右键,让项目目录变为源码目录。


MVC开始是存在于桌面程序中的,M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。


2 模型

ORM, Object Relational Mapping, 将你描述的对象映射为sql数据,语句等。
Django提供了强大的ORM。

2.1 模型类

模型类,用于代表数据库中的表结构。
修改HelloWorldPro/helloapp/models.py, 创建一个简单的学生模型类。

from django.db import models

# Create your models here.


class Student(models.Model):
    name = models.CharField(max_length=128)  # 学生名
    age = models.IntegerField()  # 学生年龄
    birthday = models.DateField()  # 出生日期

1 生成迁移文件

python manage.py makemigrations

2 执行迁移生成表

python mange.py migrate

执行完后,应该会有一个db.sqlite3的文件。

sqlite3 db.sqlite3
.tables
.schema helloapp_student
select * from sqlite_master where type="table" and name="helloapp_student";

2.2 manage.py shell基础

使用Django自带的交互环境,
增加一条数据

python manage.py shell
>>> from helloapp.models import Student
>>> stu = Student()
>>> stu.name="张三"
>>> stu.age=23
>>> from datetime import date
>>> stu.birthday = date(1998,10,10)
>>> stu.save()
>>> stu.age=44
>>> res = stu.save()
>>> print(res)
None

如果没保存成功,会出现异常。调用save之后,再次调用就是更新了
保存成功之后,在sqlite3里面可以找到这条数据。

sqlite> select * from helloapp_student;
id|name|age|birthday
1|张三|44|1998-10-10
sqlite> 

2.3 模型类相关基础操作

查询数据

python manage.py shell

all查询所有

>>> Student.objects.all()
<QuerySet [<Student: Student object (1)>]>
>>> from helloapp.models import Student
>>> Student.objects.all()
<QuerySet [<Student: Student object (1)>]>
>>> 

get查询指定条件

<QuerySet [<Student: Student object (1)>]>
>>> Student.objects.all()[0]
<Student: Student object (1)>
>>> Student.objects.all()[0].name
'张三'
>>> Student.objects.get(id=1)
<Student: Student object (1)>
>>> Student.objects.get(name="张三")
<Student: Student object (1)>
>>> 

删除数据

stu.delete()

2.4 一对多的表结构表示

方便起见,删除旧的数据库文件。然后,
修改HelloWorldPro/helloapp/models.py

from django.db import models

# Create your models here.


class Student(models.Model):
    name = models.CharField(max_length=128)  # 学生名
    age = models.IntegerField()  # 学生年龄
    birthday = models.DateField()  # 出生日期


# 多的一方 建立外键
class School(models.Model):
    name = models.CharField(max_length=128)  # 学校名
    address = models.CharField(max_length=380)  # 学校地址
    models.ForeignKey(Student, on_delete=models.CASCADE)

更新执行迁移文件:

~/PycharmProjects/django-study/HelloWorldPro » python manage.py makemigrations                                                                                                   alonebo@alonebo-pc
Migrations for 'helloapp':
  helloapp/migrations/0002_school.py
    - Create model School
(venv) ------------------------------------------------------------
~/PycharmProjects/django-study/HelloWorldPro » python manage.py migrate                                                                                                          alonebo@alonebo-pc
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, helloapp, sessions
Running migrations:
  Applying helloapp.0002_school... OK
(venv) ------------------------------------------------------------
~/PycharmProjects/django-study/HelloWorldPro »    

创建数据:

~/PycharmProjects/django-study/HelloWorldPro » python manage.py shell                                                                                                            alonebo@alonebo-pc
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from helloapp.models import Student, School
>>> stu = Student()
>>> stu.name = "张三"
>>> stu.age = 20
>>> from datetime import date
>>> stu.birthday = date(1999, 10, 10)
>>> sch = School()
>>> sch.name = "希望小学"
>>> sch.address = "北京朝阳区"
>>> stu.school = sch
>>> stu.save()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/alonebo/PycharmProjects/django-study/venv/lib/python3.6/site-packages/django/db/models/base.py", line 670, in save
    "unsaved related object '%s'." % field.name
ValueError: save() prohibited to prevent data loss due to unsaved related object 'school'.
>>> sch.save()
>>> stu.save()
sqlite3.IntegrityError: NOT NULL constraint failed: helloapp_student.school_id

The above exception was the direct cause of the following exception:

Traceback (most recent call last):

django.db.utils.IntegrityError: NOT NULL constraint failed: helloapp_student.school_id
>>> stu.
stu.DoesNotExist(              stu.clean(                     stu.full_clean(                stu.name                       stu.save(                      stu.unique_error_message(
stu.MultipleObjectsReturned(   stu.clean_fields(              stu.get_deferred_fields(       stu.objects                    stu.save_base(                 stu.validate_unique(
stu.age                        stu.date_error_message(        stu.get_next_by_birthday(      stu.pk                         stu.school                     
stu.birthday                   stu.delete(                    stu.get_previous_by_birthday(  stu.prepare_database_save(     stu.school_id                  
stu.check(                     stu.from_db(                   stu.id                         stu.refresh_from_db(           stu.serializable_value(        
>>> stu.school = sch
>>> stu.save()
>>> stu2 = Student()
>>> stu2.name = "张三"
>>> stu2.age = 10
>>> stu2.birthday = date(2000, 10, 1)
>>> stu2.school = sch
>>> stu2.save()

这里如果school对象还没调用save(),那么会报错。

ValueError: save() prohibited to prevent data loss due to unsaved related object 'school'.

然后保存之后,调用stu.save()会报完整性错误。

sqlite3.IntegrityError: NOT NULL constraint failed: helloapp_student.school_id

需要把stu.school再次赋值。

此时,数据库数据如下:

sqlite> select * from helloapp_student;
1|张三|20|1999-10-10|1
2|张三|10|2000-10-01|1
sqlite> select * from helloapp_school;
1|希望小学|北京朝阳区

由一查多(从School查询Student)
使用obj.xxx_set

>>> from helloapp.models import Student,School
>>> sch = School.objects.get(name="希望小学")
>>> sch
<School: School object (1)>
>>> sch.address
'北京朝阳区'
>>> sch.student_set.all()
<QuerySet [<Student: Student object (1)>, <Student: Student object (2)>]>
>>> 

由多查一(从Student查询School)
使用obj.外键名

>>> from helloapp.models import Student,School
>>> stu1 = Student.objects.all()[0]
>>> stu1
<Student: Student object (1)>
>>> stu1.name
'张三'
>>> stu1.school
<School: School object (1)>
>>> stu1.school.name
'希望小学'
>>> 

相关文章

网友评论

    本文标题:Django-01 Start

    本文链接:https://www.haomeiwen.com/subject/zrlsbqtx.html