欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

自强学堂 10) Django 模型(数据库)

shiping1 的头像

Django 模型是与数据库相关的,与数据库相关的代码一般写在 models.py 中,Django 支持 sqlite3, MySQL, PostgreSQL等数据库,只需要在settings.py中配置即可,不用更改models.py中的代码,丰富的API极大的方便了使用。

本节的代码:(Django 1.6, Python 2.7 测试环境)

learn_models.zip

大家可以按照我的步骤来开始做:

1
2
3
django-admin.py startproject learn_models # 新建一个项目
cd learn_models # 进入到该项目的文件夹
django-admin.py startapp people # 新建一个 people 应用(app)

补充:新建app也可以用 python manage.py startapp people, 需要指出的是,django-admin.py 是安装Django后多出的一个命令,并不是指一个 django-admin.py 脚本在当前目录下。

那么project和app什么关系呢,一个项目一般包含多个应用,一个应用也可以用在多个项目中。

 

将我们新建的应用(people)添加到 settings.py 中的 INSTALLED_APPS中,也就是告诉Django有这么一个应用。

1
2
3
4
5
6
7
8
9
10
INSTALLED_APPS = (
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
 
    'people',
)

我们打开 people/models.py 文件,修改其中的代码如下:

1
2
3
4
5
from django.db import models
 
class Person(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()

我们新建了一个Person类,继承自models.Model, 一个人有姓名和年龄。这里用到了两种Field,更多Field类型可以参考教程最后的链接。

 

我们来同步一下数据库

1
2
3
4
5
python manage.py syncdb # 进入 manage.py 所在的那个文件夹下输入这个命令
 
注意:Django 1.7 及以上的版本需要用以下命令
python manage.py makemigrations
python manage.py migrate

我们会看到,Django生成了一系列的表,也生成了我们新建的people_person这个表,那么如何使用这个表呢?

Django提供了丰富的API, 下面演示如何使用它。

1
2
3
4
5
6
$ python manage.py shell
 
>>> from people.models import Person
>>> Person.objects.create(name="WeizhongTu", age=24)
<Person: Person object>
>>>

我们新建了一个用户WeizhongTu 那么如何从数据库是查询到它呢?

1
2
3
>>> Person.objects.get(name="WeizhongTu")
<Person: Person object>
>>>

我们用了一个 .objects.get() 方法查询出来符合条件的对象,但是大家注意到了没有,查询结果中显示<Person: Person object>,这里并没有显示出与WeizhongTu的相关信息,如果用户多了就无法知道查询出来的到底是谁,查询结果是否正确,我们重新修改一下 people/models.py

name 和 age 等字段中不能有 __(双下划线,因为在Django QuerySet API中有特殊含义(用于关系,包含,不区分大小写,以什么开头或结尾,日期的大于小于,正则等)

也不能有Python中的关键字,name 是合法的,student_name 也合法,但是student__name不合法,try, class, continue 也不合法,因为它是Python的关键字( import keyword; print(keyword.kwlist) 可以打出所有的关键字)

1
2
3
4
5
6
7
8
9
10
from django.db import models
 
 
class Person(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()
    
    def __unicode__(self):
    # 在Python3中使用 def __str__(self)
        return self.name

按CTRL + C退出当前的Python shell, 重复上面的操作,我们就可以看到:

新建一个对象的方法有以下几种:

  1. Person.objects.create(name=name,age=age)

  2. p = Person(name="WZ", age=23)

    p.save()

  3. p = Person(name="TWZ")

    p.age = 23

    p.save()

  4. Person.objects.get_or_create(name="WZT", age=23)

    这种方法是防止重复很好的方法,但是速度要相对慢些,返回一个元组,第一个为Person对象,第二个为True或False, 新建时返回的是True, 已经存在时返回False.

 

获取对象有以下方法:

  1. Person.objects.all()

  2. Person.objects.all()[:10] 切片操作,获取10个人,不支持负索引,切片可以节约内存

  3. Person.objects.get(name=name)

     

    get是用来获取一个对象的,如果需要获取满足条件的一些人,就要用到filter

  4. Person.objects.filter(name="abc") # 等于Person.objects.filter(name__exact="abc") 名称严格等于 "abc" 的人

  5. Person.objects.filter(name__iexact="abc") # 名称为 abc 但是不区分大小写,可以找到 ABC, Abc, aBC,这些都符合条件

     

  6. Person.objects.filter(name__contains="abc") # 名称中包含 "abc"的人

  7. Person.objects.filter(name__icontains="abc") #名称中包含 "abc",且abc不区分大小写

     

  8. Person.objects.filter(name__regex="^abc") # 正则表达式查询

  9. Person.objects.filter(name__iregex="^abc")# 正则表达式不区分大小写

     

    filter是找出满足条件的,当然也有排除符合某条件的

  10. Person.objects.exclude(name__contains="WZ") # 排除包含 WZ 的Person对象

  11. Person.objects.filter(name__contains="abc").exclude(age=23) # 找出名称含有abc, 但是排除年龄是23岁的

     

参考文档:

Django models 官方教程: https://docs.djangoproject.com/en/dev/topics/db/models/

Fields相关官方文档:https://docs.djangoproject.com/en/dev/ref/models/fields/

 
 
 
  • MrL

    django-admin.py startapp people # 新建一个 people 应用(app)
    这个应该是Python manage.py startapp people吧

  • 阿文

    我django1.6.11版本,setting里设置连得mysql数据库,python manage.py dbshell 可以直接进到数据库里,但python manage.py syncdb却一直报错,麻烦帮看看:
    [root@kvm lala]# python manage.py syncdb
    Traceback (most recent call last):
    File "manage.py", line 10, in 
    execute_from_command_line(sys.argv)
    File "/usr/lib/python2.6/site-packages/django/core/management/__init__.py", line 399, in execute_from_command_line
    utility.execute()
    File "/usr/lib/python2.6/site-packages/django/core/management/__init__.py", line 392, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
    File "/usr/lib/python2.6/site-packages/django/core/management/base.py", line 242, in run_from_argv
    self.execute(*args, **options.__dict__)
    File "/usr/lib/python2.6/site-packages/django/core/management/base.py", line 284, in execute
    self.validate()
    File "/usr/lib/python2.6/site-packages/django/core/management/base.py", line 310, in validate
    num_errors = get_validation_errors(s, app)
    File "/usr/lib/python2.6/site-packages/django/core/management/validation.py", line 34, in get_validation_errors
    for (app_name, error) in get_app_errors().items():
    File "/usr/lib/python2.6/site-packages/django/db/models/loading.py", line 196, in get_app_errors
    self._populate()
    File "/usr/lib/python2.6/site-packages/django/db/models/loading.py", line 75, in _populate
    self.load_app(app_name, True)
    File "/usr/lib/python2.6/site-packages/django/db/models/loading.py", line 99, in load_app
    models = import_module('%s.models' % app_name)
    File "/usr/lib/python2.6/site-packages/django/utils/importlib.py", line 40, in import_module
    __import__(name)
    File "/opt/lala/people/models.py", line 4
    Class Person(models.Model):
    ^
    SyntaxError: invalid syntax

  • liuhang

    为什么我只有django-admin startproject才会新建项目,还有python manage.py syncdb同步数据库的时候没有创建各种表。。

    • 前 面有讲到的,如果你是linux比如用apt-get安装的,应该就是 django-admin 如果是用 pip 安装的 Django 应该就是 django-admin.py。至于 syncdb 不同步表,你可以试试 python manage.py migrate,各版本之间有些不同,建议安装 最新的 Django 1.8,用pip安装,原来用apt-get 安装的 Django 可以删除掉

      • liuhang

        十分感谢,我再试试,有不明白的我会继续请教的

  • 你好,在python manage.py syncdb 这条命令里,报错了:Unknown command 'syncdb'.这是怎么回事?

    • Django 1.7早期的版本可能会出现这个情况,可以使用 python manage.py migrate 试试,最新版的 Django 1.7和 Django 1.8都是可以使用 python manage.py syncdb的

  • Tigeraus

    创建app的那条命令“django-admin.py stratapp people”是否有误?因为在learn_models下并没有django-admin.py文件

    • 没有问题的,django-admin.py 是一个命令,可以用它新建project,也可以建 app

  • 201761625
    201761625

    讲的很容易懂,谢谢分享 [威武]

  • 阿凯

    学到Django模型,收获很大

  • 为什么我在models.py中写了self函数,从下载的本节代码的models.py中粘过来的,执行get方法,也一样不显示具体名字,显示的是Person object , 哪里有问题呢?

  • 李亦然

    忘记了数据库的账号怎么处理?

    • 学习的话可以用sqlite3数据库,不用配置的,等真正部署的时候再用MySQL或者是PostgreSQL也不迟的

  • 李亦然

    Person.objects.filter(name__contains="abc") 
    Person.objects.filter(name__icontains="abc")
    为什么我通过这两种方法获取到的都是包含大小写的abc呢?

    • 可能是数据库中没有大写的ABC或者Abc这样的,你自己创建之后再查询试试,有问题再回复。

  • 李亦然

    新建对象的方法第4中,Person.object.get_or_create(name="WZT", age=23),Person中没有object,应该是objects。

  • 不错的教程,看了有很大的帮助

  • yu

    我获取对象的前三种方法能用,后面的方法中报错。Cannot resolve keyword 'name_contains' into field. choices are:age,id,name

  • 红日

    你好为什么我只能在scripts目录下创建startproject mysite,然后进入cd mysite,再创建startapp blog就会提示django-admin不是内部或外部命令呢

  • 这里用的sqlite3 同步数据到时候:
    [root@localhost website]# python manage.py syncdb
    Operations to perform:
    Apply all migrations: admin, contenttypes, auth, sessions
    Running migrations:
    No migrations to apply.
    Your models have changes that are not yet reflected in a migration, and so won't be applied.
    Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.

    根据提示要运行:
    [root@localhost website]# python manage.py makemigrations
    Migrations for 'Blog':
    0001_initial.py:
    - Create model Person

    然后再Syncdb:
    [root@localhost website]# python manage.py syncdb
    Operations to perform:
    Apply all migrations: Blog, admin, contenttypes, auth, sessions
    Running migrations:
    Applying Blog.0001_initial... OK

    You have installed Django's auth system, and don't have any superusers defined.
    Would you like to create one now? (yes/no): yes
    Username (leave blank to use 'root'): 
    Email address: 
    Password: 
    Password (again): 
    Superuser created successfully.
    [root@localhost website]#

    • 这里我建的APP是Blog

      • 是 的,Django 1.7是集成了 south 的功能,相当于 models.py(数据库) 的版本控制,要运行两条:python manage.py makemigrations 来记录models.py 的更改,python manage.py migrate 再进行真正的更改

  • 新建的应用是people 怎么能是打开 user/models.py 文件呢?


来自 http://www.ziqiangxuetang.com/django/django-models.html
普通分类: