zoukankan      html  css  js  c++  java
  • Django templates and models

    • models

    • templates

    • models and databases

    models

    如何理解models

    A model is the single, definitive source of information about your data.

    It contains the essential fields and behaviors of the data you’re storing.

    Generally, each model maps to a single database table.

    The basics:

    • Each model is a Python class that subclasses django.db.models.Model.
    • Each attribute of the model represents a database field.
    • With all of this, Django gives you an automatically-generated database-access API; see Making queries.

    quick example

    from django.db import models
    
    class Person(models.Model):
        first_name = models.CharField(max_length=30)
        last_name = models.CharField(max_length=30)
    View Code

    The above Person model would create a database table like this:

    CREATE TABLE myapp_person (
        "id" serial NOT NULL PRIMARY KEY,
        "first_name" varchar(30) NOT NULL,
        "last_name" varchar(30) NOT NULL
    );
    View Code

    注意:表名是    ---应用名字_class名字 ,你可以重写他们

    ID字段是自动添加的,并设置为主键,当然你也可以重写他们

    要想使写的model在数据库生效,你需要在 INSTALLED_APPS中添加进你的应用,像这样

    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'books.apps.BooksConfig',
    ]
    View Code

    books 是我的app name, BooksConfig 是apps.py 文件中定义的类名

    使用以下两条命令

    python manage.py makemigrations
    
    python manage.py migrate
    View Code

    执行第一条命令后你会在migrations文件夹中看到0001_initial.py文件

    manage.py migrate  这条命令是迁移到数据库,数据库中会有你创建的表

    Fileds(字段)

    数据表中的字段被class attributes  所指定。需要注意的是,字段的名字不要和model API 冲突,like   clear delete save

    example

    from django.db import models
    
    class Musician(models.Model):
        first_name = models.CharField(max_length=50)   
        last_name = models.CharField(max_length=50)
        instrument = models.CharField(max_length=100)
    
    class Album(models.Model):
        artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
        name = models.CharField(max_length=100)
        release_date = models.DateField()  
        num_stars = models.IntegerField()
    View Code

    field options

    以下是字段常用的参数

    • null    如果是True,  django会将空值存储为null在数据库中,默认是False
    • default   The default value for the field. This can be a value or a callable object. If callable it will be called every time a new object is created.
    • choice   An iterable (e.g., a list or tuple) of 2-tuples to use as choices for this field. If this is given,the default form widget will be a select box instead of the standard text field and will limit choices to the choices given.
    • blank(空白)     If True, the field is allowed to be blank. Default is False.
    • primary key  如果是True  ,指定这个字段是主键
    • unique    如果是True    这个字段数据唯一的,不能重复

    关于field name 的约束

    django 对于field name 只有两个约束

    1. 不能是Python的保留字,比如pass  for try 等,否则会出现语法错误
    2. 字段名字不能包含超过1个下划线 (_)  这是由于django 的查询语法的工作模式导致的
    class Example(models.Model):
        foo__bar = models.IntegerField() 
    # 'foo__bar' has two underscores!
    View Code

    making query   查询

    一旦你创建了数据模型,django会自动提供数据库抽象API让你创建,更新,删除object

    refer to the following models

    from django.db import models
    
    class Blog(models.Model):
        name = models.CharField(max_length=100)
        tagline = models.TextField()
    
        def __str__(self):              # __unicode__ on Python 2
            return self.name
    
    class Author(models.Model):
        name = models.CharField(max_length=200)
        email = models.EmailField()
    
        def __str__(self):              # __unicode__ on Python 2
            return self.name
    
    class Entry(models.Model):
        blog = models.ForeignKey(Blog)
        headline = models.CharField(max_length=255)
        body_text = models.TextField()
        pub_date = models.DateField()
        mod_date = models.DateField()
        authors = models.ManyToManyField(Author)
        n_comments = models.IntegerField()
        n_pingbacks = models.IntegerField()
        rating = models.IntegerField()
    
        def __str__(self):              # __unicode__ on Python 2
            return self.headline
    View Code
    creating object

    Django uses an intuitive system:

    A model class represents a database table, and an instance of that class represents a particular record in the database table.

    模型类代表数据表,这个l类的实例代表这个数据表中一个特定的实例。

    >>> from blog.models import Blog
    >>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.') name是blog类中的属性,即指定的字段
    >>> b.save()

    这个行为相当于在幕后执行了INSERT SQL 语句

    这是一种插入数据的方式,还有另一种插入数据的方式:

    >> Blog.object.create(name="libai",tagline="all the latest beatles news")

    这种方式不需要save

    Saving changes to objects

    使用.save()来保存改变的对象

    例如

    b.name="李白"

    b.save()

    retrieving object(检索对象)

    To retrieve objects from your database, construct a QuerySet via a Manager on your model class.

    为了检索从数据库的对象,通过model类的manage方法构建一个QuerySet

    关于manage方法,如果不设置名字,默认名字是objects

    A QuerySet  represents a collection of objects from your database. It can have zero, one or many filters.

    QuertSet 代表数据库中对象的集合,他有0个,1个或者多个过滤器  从SQL角度来看,QuerySet相当于select语句,filter相当于where  having

    You get a QuerySet by using your model’s Manager. Each model has at least one Manager, and it’s called objects by default. Access it directly via the model class, like so:

    NOtes:

    实例是没有manage方法的

    like:

    >>> Blog.objects
    <django.db.models.manager.Manager object at ...>
    >>> b = Blog(name='Foo', tagline='Bar')
    >>> b.objects
    Traceback:
        ...
    AttributeError: "Manager isn't accessible via Blog instances."

    检索所有的objects

    all_entries=Entry.objects.all()

    很多f情况下我们需要匹配特定的,这时需要用到过滤器

    Retrieving specific objects with filters

    两种方法:

    filter(**kwargs)

    Returns a new QuerySet containing objects that match the given lookup parameters.

    excludet(**kwargs)

    Returns a new QuerySet containing objects that do not match the given lookup parameters.

    For example, to get a QuerySet of blog entries from the year 2006, use filter() like so:

    Entry.objects.filter(pub_date__year=2006)
    With the default manager class, it is the same as:
    Entry.objects.all().filter(pub_date__year=2006)

    Retrieving a single object with get()

    filter() will always give you a QuerySet, even if only a single object matches the query - in this case, it will be a QuerySetcontaining a single element.

    使用get()会返回一个object

    你就可以直接使用它

    查询表达式

    from django.db.models import F, Count, Value
    from django.db.models.functions import Length, Uppe

    F()  表达式

    An F() object represents the value of a model field or annotated column. It makes it possible to refer to

    model field values and perform database operations using them without actually having to pull them

    out of the database into Python memory.

    Instead, Django uses the F() object to generate an SQL expression that describes the required operation at the database level.

    # Tintin filed a news story!
    reporter = Reporters.objects.get(name='Tintin')
    reporter.stories_filed += 1
    reporter.save()

    使用F()

    from django.db.models import F
    
    reporter = Reporters.objects.get(name='Tintin')
    reporter.stories_filed = F('stories_filed') + 1
    reporter.save()

    F() 代表了一个model field或者annatate column上的value, 优点在于不用将数据库数据拿出来放到Python 内存中

    F() 常用于update 语句中

    reporter = Reporters.objects.filter(name='Tintin')
    reporter.update(stories_filed=F('stories_filed') + 1)

    F() therefore can offer performance advantages by:

    • getting the database, rather than Python, to do work
    • reducing the number of queries some operations require

     To access the new value saved this way, the object must be reloaded:

     如果你想立刻获得更新的值的话,执行     注释:这句理解可能有误

    reporter.refresh_from_db()
    reporter = Reporters.objects.get(pk=reporter.pk)
    # Or, more succinctly:
    reporter.refresh_from_db()

     Django 静态文件部署

    以下是几个概念

    • STATIC_ROOT
    • STATIC_URL
    • STATICFILES_DIR
    • STATICFILES_STORAGE
    • STATICFILES_FINDERS

    STATIC_ROOT

    default :none

    The absolute path to the directory where collectstatic will collect static files for deployment  

    目录的绝对路径,当执行python manage.py collectstatic 命令时,会将收集的静态文件全部放到这个目录下

    一般来说这个目录下应该没有文件,是空的目录

    例如

    STATIC_ROOT="/var/www/example.com/static/"  

    STATIC_URL

    default :none

    URL to use when referring to static files located in STATIC_ROOT

    Example: "/static/" or "http://static.example.com/"

    如果这个值不是空值,必须要以 /  结尾

    STATICFILES_DIRS

    default::[]  empty list

    This setting defines the additional locations the staticfiles app will traverse if the FileSystemFinder finder is enabled,

    这个设置将定义了一个额外的位置, staticfiles app将会遍历这个位置,如果FileSystemFinder finde能够被使用

    for example

    STATICFILES_DIRS = [
        "/home/special.polls.com/polls/static",
        "/home/polls.com/polls/static",
        "/opt/webfiles/common",
    ]

    STATICFILES_FINDERS

    default:
    [ 'django.contrib.staticfiles.finders.FileSystemFinder', 'django.contrib.staticfiles.finders.AppDirectoriesFinder', ]

    The list of finder backends that know how to find static files in various locations.

    查找器的一个列表,知道如何从不同的位置找到静态文件

    The default will find files stored in the STATICFILES_DIR setting (using django.contrib.staticfiles.finders.FileSystemFinder) and in a static subdirectory of each app (usingdjango.contrib.staticfiles.finders.AppDirectoriesFinder). If multiple files with the same name are present, the first file that is found will be used.

    One finder is disabled by default: django.contrib.staticfiles.finders.DefaultStorageFinder. If added to your STATICFILES_FINDERS setting,

    it will look for static files in the default file storage as defined by the DEFAULT_FILE_STORAGE setting.

    template

    template   模板

    变量 variables

    标签  tag

    过滤器 filter

    模板是一个简单的text文件,包括变量(获得值)和标签(控制逻辑)

    变量  {{ variable }}

    自定义模板标签和filters

    1 确定你的app在settings.py 的installed_app中

    2然后在你的app中应该有一个templatetags包,

    3在templatetag目录下,创建一份文件去自定义标签,例如这个文件名叫myappcustomtag.py

    4在你的template总加入这个语句

    {% load myappcustomtag %}

    在myappcustomtag.py 这个module中的前面加入这几句

    from django import template
    
    register = template.Library()
    目的是让你的模块成为一个有效的标签库
    5开始写你自定义的filter或者tag
    定义一个函数
    给函数加上一个装饰器,
    @register.filter
    像下面这样
    @register.filter
    def cut(value, arg): return value.replace(arg, '')


    @register.simple_tag
    代码如下:
    @register.simple_tag
    def current_time(format_string):
        return datetime.datetime.now().strftime(format_string)

     模板继承

    你需要一个模板,作为母版,例如base.html

    在子模板中加入以下语句

    {% extends %}

    需要注意两点

    {% extends " base.html" %} 必须是这个模板中的第一个标签,否则将不会起效果

    {% block %} 标签越多越好

    如果你想获得母版中block中的值,使用{% block.super%}

    在同一个模板中block的名字不能相同

    models and database

    查询数据库中的记录

    get()    filter()     all()

    更新

    使用queryset的方法update()

    第二种方法   获取instance object  ,直接赋值,然后 调用save()方法

    删除

    delete()

    关于query expression

    介绍两个

    F()  Q()

    导入

    from django.db.models import F,Q

    可以用在update, create, filter, order by, annotation, or aggregate.

    支持算术,加减乘除

    F() EXPRESSION

    An F() object represents the value of a model field or annotated column

    F()代表了model字段的值或者注释列   它直接操作数据库,通过注入SQL语句,而不是吧数据从数据库拉到Python的内存中

    使用F()有以下几个优势

    • getting the database, rather than Python, to do work
    • reducing the number of queries some operations require

    直接用数据库而不是Python, 减少了查询操作需求的数量

    另外还可以avoild race condition   在使用Python mulitiple thread  要注意这点

    F() objects assigned to model fields persist after saving the model instance and will be applied on each save(). For example:

    reporter = Reporters.objects.get(name='Tintin')
    reporter.stories_filed = F('stories_filed') + 1
    reporter.save()
    
    reporter.name = 'Tintin Jr.'
    reporter.save()

    stories_filed will be updated twice in this case. If it’s initially 1, the final value will be 3.

     bk=Book.objects.get(id=2)
        # t=Book.objects.filter(auth__name='李白').values('title','price')
    
        # print(t)# 
        bk.price=F('price')/2
        print("-------------------------------")
        bk.save()
        bk.title='唐诗三百首'
        bk.save()
        return HttpResponse("ok")

    关于queryset API reference

    queryset  对象是可迭代的,

    支持切片[1:3]

    支持pickle

    len()

     b=len(Book.objects.all())

    list()  将queryset转化为列表

     b=list(Book.objects.all())

    切片后也是query对象,但是这个对象不再支持更远的修改,排序等操作,因为它已经不能很好的转化为SQL,没有了明确的定义

     bk=Book.objects.get(id=2)
        # t=Book.objects.filter(auth__name='李白').values('title','price')
        b=Book.objects.all()[0:3]
        print(b)
        print(b.order_by('price'))

    比如执行以上的代码,会出现以下错误

    Methods that return new QuerySets

    filter(**kwargs)

    exclude(**kwargs)

    annotate(*args**kwargs)

    order_by(*field)

    reverse()  

    values(*fields**expressions)

    aggregate(*args**kwargs)

    exists()

    update(**kwargs)

    delete()

    annotate   的参数可以是一个值,字段,查询表达式,聚合表达式,

    除了聚合表达式可以是匿名参数,其他任何参数必须是关键字参数

    annaotate 都指定一个关键字参数作为alias   别名

     from django.db.models import Count,Avg ,Sum,Max
        b = Book.objects.values('auth__name').annotate(maxprice=Max('price'))
        print(b[0]['maxprice'])

    如果里面是聚合表达式,会默认将聚合和models field combine  as alias 

     使用reverse()   必须是已经排序了,要么调用了order_by  或者定义了ordering,otherwise ,no effect

    values(*fields**expressions)

    Returns a QuerySet that returns dictionaries, rather than model instances, when used as an iterable.

    返回一个requeryset  ,里面包含的是字典,而不是model instance

    values 有一个可选的位置参数,*field   如果制定了字段,则字典只包含指定的字段

    aggregate(*args**kwargs)

    返回一个字典,

    aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典。键的名称是聚合值的
    标识符,值是计算出来的聚合值。键的名称是按照字段和聚合函数的名称自动生成出来的。如果你想要为聚合值指定
    一个名称,可以向聚合子句提供它:
    >>> Book.objects.aggregate(average_price=Avg('price'))
    {'average_price': 34.35}

     

    exists()

    Returns True if the QuerySet contains any results, and False if not. 

  • 相关阅读:
    CS round--36
    Vijos 1002 过河 dp + 思维
    汇编模拟36选7
    1137
    E. Mike and Foam 容斥原理
    Even-odd Boxes hackerrank 分类讨论
    112. 作业之地理篇 最小费用最大流模板题
    1550: Simple String 最大流解法
    Sam's Numbers 矩阵快速幂优化dp
    java.sql.SQLSyntaxErrorException: ORA-01722: 无效数字
  • 原文地址:https://www.cnblogs.com/yuyang26/p/7419342.html
Copyright © 2011-2022 走看看