django学习笔记

django

一、model

   model层是与数据库相关联的层,每一个类映射到一个数据表

   对于model有一些注意点:

   1、主键

     如果不设置 primary_key=True 对所有的类属性, 将自动增加一个整数递增来作为主键 (如果对原来的表修改主键,新表和旧表会同时存在吗)

   2、choices

    choices是一个元组,第一个参数会存储到数据库,第二个参数我觉着就是对第一个参数的具体描述

  3、对应关系

     1、ForeignKey

from django.db import models

class Manufacturer(models.Model):
    # ...
    pass

class Car(models.Model):
    manufacturer = models.ForeignKey(Manufacturer, on_delete=models.CASCADE) # models.CASCADE表示如果主表记录删除,则关联表相关记录也应该删除

 

class Person(models.Model):
    SHIRT_SIZES = (
        ('S', 'Small'),
        ('M', 'Medium'),
        ('L', 'Large'),
    )
    name = models.CharField(max_length=60)
    shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)

>>> p = Person(name="Fred Flintstone", shirt_size="L")
>>> p.save()
>>> p.shirt_size
'L'
>>> p.get_shirt_size_display()
'Large'

    4、class Meta(object) 

    给model定义元数据,比如排序

ordering = ['-order_date']  表示降序
ordering = ['order_date']  表示升序

 

 5、 annotate 参考博客

      annotate主要用来统计在某个相关联表下的数量

 

    
       
       
       
       
  
   
   

 

Post 表:
id    title    body    category_id
1     post 1     ...     1
2     post 2     ...     1
3     post 3     ...     1
4     post 4     ...     2

Category 表:
name    id
category 1     1
category 2     2


blog/templatetags/blog_tags.py

from django.db.models.aggregates import Count
from blog.models import Category

@register.simple_tag
def get_categories():
    # 记得在顶部引入 count 函数
    # Count 计算分类下的文章数,其接受的参数为需要计数的模型的名称
    return Category.objects.annotate(num_posts=Count('post')).filter(num_posts__gt=0)

这个 Category.objects.annotate 方法和 Category.objects.all 有点类似,它会返回数据库中全部 Category 的记录,但同时它还会做一些额外的事情,
在这里我们希望它做的额外事情就是去统计返回的 Category 记录的集合中每条记录下的文章数。代码中的 Count 方法为我们做了这个事,它接收一个和 Categoty
相关联的模型参数名(这里是 Post,通过 ForeignKey 关联的),然后它便会统计 Category 记录的集合中每条记录下的与之关联的 Post 记录的行数,也就是文章数
,最后把这个值保存到 num_posts 属性中。

 

django操作数据库

进入到shell,利用model进行操作

mysql> describe user_app_topic
    -> ;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id         | int(11)     | NO   | PRI | NULL    | auto_increment |
| text       | varchar(20) | NO   |     | NULL    |                |
| date_added | datetime(6) | NO   |     | NULL    |                |
+------------+-------------+------+-----+---------+----------------+
3 rows in set (0.02 sec)

mysql> describe user_app_entry
    -> ;
+------------+-------------+------+-----+---------+----------------+
| Field      | Type        | Null | Key | Default | Extra          |
+------------+-------------+------+-----+---------+----------------+
| id         | int(11)     | NO   | PRI | NULL    | auto_increment |
| text       | longtext    | NO   |     | NULL    |                |
| date_added | datetime(6) | NO   |     | NULL    |                |
| topic_id   | int(11)     | NO   | MUL | NULL    |                |
+------------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

 

>>> from user_app.models import Topic, Entry
>>> topic = Topic(text="Chess")
>>> topic.save()
>>> topic = Topic(text="Climbing")
>>> topic.save()
>>> Topic.objects.all()
[<Topic: Chess>, <Topic: Climbing>]
>>> entry = Entry(topic_id = 1,text="The opening is the first part of the game, roughly the first ten moves or so.")
>>> entry.save()
>>> t = Topic.objects.get(id=1)
>>> t.text
u'Chess'

 

4、select_related 和 prefetch_related

    select_related主要在查询外键使用,在select_related()里面加入指定的外键可以将关联的对象也一并查询出来,与普通相比减少了查询次数,select_related主要用于一对一,一对多(foreignkey),它的实现原理就是与关联表进行 inner join 具体讲解

    prefetch_related主要用于多对多关系的查询,他不能使用join 进行连接,因为多对多的关系使用join进行连接会使得生成的表非常长,效率不高。他是先查询一个表,在根据python处理他们之间的关系 具体讲解

  

 5、related_name

    related_name是关联对象反向引用

class Apple( models.Model):
    origin_level = models.ForeignKey(AppleLevel, related_name='orgin_level_appleset')
    new_level = models.ForeignKey(AppleLevel, related_name='new_level_appleset')

通过origin_level引用AppleLevel 中id为12的Apple的所有对象
AppleLevel.object.get(id=12).origin_level_appleset.objects.all()

 

 

 

Form

ModelForm https://www.jianshu.com/p/3d04309445e4

1、

 

 

 

二、view

    1、django.shortcuts

        render(request, template_name, context=None, content_type=None, status=None, using=None)

     2、class-base-views 基于类的通用视图

https://www.jianshu.com/p/00bf223873b3

 

Mixin

        Django把基本的http请求和响应抽象出来, 封装成各自的类, 在使用过程中只需把各个基类聚合到一起使用, 并按照自己的要求重写自己需要的方法就可以了, 那么就把这些基类叫Mixin吧. 在Django中比较基础的Mixin主要有几类:

  1. View(视图基础类)

  2. SingleObjectMixin(单对象类)

  3. MultipleObjectMixin(多对象类)

  4. TemplateResponseMixin(模板响应类)

  5. FormMixin(表单类)

  6. YearMixin, MonthMixin, DayMixin, WeekMixin, DateMixin(几个基于时间关系的类)

 TemplateView

TemplateView继承 View, ContextMixin, TemplateResponseMinxin

View类提供as_view()方法,在这个方法中要做的事情就是dispatch

ContextMixin类只实现了一个方法 get_context_data

TemplateResponseMixin 在render_to_response()方法中返回一个TemplateResponse对象,template用的就是类属性template_name指定的

from django.views.generic import TemplateView

class AboutView(TemplateView):
    template_name = "about.html"

 

FormMixin

提供 form_class 指定form表单,

方法中有: form_valid(self, forml) 判断form是否有效,若有效转向 get_success_url

 

 ListView: 获取一系列的model然后将其封装到context中

 

在ListView中有两个主要的函数 get_queryset() 和 get_context_data(),

get_queryset()主要就是取查询model, 类似于article_list = Article.objects.all(), 如果只是单纯的查询就不需要重写, 直接指名一个查询的model即可(model = Article); get_context_data 就是把查询到的内容添加到context中, kwargs应该指的就是context,如果还需要再添加内容就要重写该方法,如下代码所示。

return super(IndexView, self).get_context_data(**kwargs) 语句的作用是添加了 category_list 到上下文中,还要把默认的一些上下文变量也返回给视图函数,以便其后续处理

class IndexView(ListView):
    template_name = "blog/index.html" #需要渲染的模板文件
    context_object_name = "article_list" #get_queryset返回的list,如果不指定名字,默认位object_list

    def get_queryset(self):
        article_list = Article.objects.all()
        for article in article_list:
            article.body = markdown2.markdown(article.body, extras=['fenced-code-blocks'], )
        return article_list

    def get_context_data(self, **kwargs):
        kwargs['category_list'] = Category.objects.all().order_by('name')
        return super(IndexView, self).get_context_data(**kwargs)

 DetailView

detailview依赖于SingleObjectMinxin,

get_object方法它根据请求的URL来确定对象

get_object 方法默认情况下获取 id 为pk_url_kwarg 的对象

 

class ArticleDetailView(DetailView):
    model = Article
    template_name = "blog/detail.html"
    context_object_name = "article"
    pk_url_kwarg = 'article_id' #根据什么来去

    def get_object(self, queryset=None):
        obj = super(ArticleDetailView, self).get_object()
        obj.body = markdown2.markdown(obj.body, extras=['fenced-code-blocks'], )
        return obj

 

    form

 

Templates

1、模板里面可以使用四则运算

  {{ num|add:1}} 表示加一操作

2、可以自定义filters来对templates里面的数据进行处理,具体操作过程

    1、在 应用目录(app)下 创建templatetags文件夹,在templatetags文件夹下创建app_filters.py

    2、app_filters.py

from django import template

register = template.Library()

@register.filter(name='get_due_date_string')
def get_due_date_string(value):
    delta = value - date.today()

    if delta.days == 0:
        return "Today!"
    elif delta.days < 1:
        return "%s %s ago!" % (abs(delta.days),
            ("day" if abs(delta.days) == 1 else "days"))
    elif delta.days == 1:
        return "Tomorrow"
    elif delta.days > 1:
        return "In %s days" % delta.days

3、在templates里面加入注释,如果是单行注释 {# #},如果是多行注释 {% comment %} {% endcomment %}

4、 如果使用赋值语句需要在 {with } {with}里面

posted @ 2017-07-23 20:28  zhaop  阅读(421)  评论(0编辑  收藏  举报