django 基础

创建django 项目

django-admin startproject mysite

目录介绍
        mysite
            - mysite        # 对整个程序进行配置
                - init
                - settings  # 配置文件
                - url       # URL对应关系
                - wsgi      # 遵循WSIG规范,生产环境中一般不用django自带的wsgi,而是这个uwsgi + nginx
            - manage.py     # 管理Django程序:
                                - python manage.py
                                - python manage.py startapp xx
                                - python manage.py makemigrations
                                - python manage.py migrate

创建app

python manage.py startapp cmdb

cmdb:
        migrations     数据修改表结构,django根据这个来判断表是否有改动,有改动就可以通过命令更新数据库中的表结构
        admin          Django为我们提供的后台管理
        apps           配置当前app
        models         ORM,写指定的类  通过命令可以创建数据库结构
        tests          单元测试
        views          业务代码

创建完项目后的基本配置:

数据库

 1 DATABASES = {
 2     'default': {
 3     'ENGINE': 'django.db.backends.mysql',
 4     'NAME':'dbname',
 5     'USER': 'root',
 6     'PASSWORD': 'xxx',
 7     'HOST': '',
 8     'PORT': '',
 9     }
10 }
数据库
# 由于Django内部连接MySQL时使用的是MySQLdb模块,而python3中还无此模块,所以需要使用pymysql来代替
  
# 如下设置放置的与project同名的配置的 __init__.py文件中
  
import pymysql
pymysql.install_as_MySQLdb() 
 
 
 
模板
1 TEMPLATE_DIRS = (
2         os.path.join(BASE_DIR,'templates'),
3     )
4 #这里就是配置模板文件夹的可以将 'templates’改成自己的
模板文件夹配置

静态文件

1 STATIC_URL = '/static/'
2 STATICFILES_DIRS = (
3         os.path.join(BASE_DIR,'static'),
4     )
定义静态文件

路由系统:

 
 
 
 
 
视图基本方法:
 1 def func(request):
 2                 # request.method   GET / POST
 3                 
 4                 # http://127.0.0.1:8009/home?nid=123&name=alex
 5                 # request.GET.get('',None)   # 获取请求发来的而数据
 6                 
 7                 # request.POST.get('',None)
 8                 
 9                 
10                 # return HttpResponse("字符串")
11                 # return render(request, "HTML模板的路径",{"obj":obj 给前端模板传递参数这里也可以用locals()传递所有本地变量})
12                 # return redirect('/只能填URL   /home) 这里就又转发给url,然后转给home视图

获取数据基本方法

request.POST

request.GET

request.FILES

获取checkbox和select多选参数
request.POST.getlist('city')#获取的name



上传文件
    # 上传文件,form标签做特殊设置增加enctype="multipart/form-data
    obj = request.FILES.get('image')
    obj.name #输出文件名字,如果打印obj实际返回的也是文件名,因为在类中定义了__str__或__repr__ 来指定类返回的输出,str优先级高于repr
#obj的type ===》<class 'django.core.files.uploadedfile.InMemoryUploadedFile'> f
= open(obj.name, mode='wb') for item in obj.chunks(): f.write(item) f.close()

模板渲染基本方式:

获取变量
<div>{{current_user}}</div>


for循环
{% for k,v in user_list.items %}
      {{ k }}:{{ v }}
{% endfor %}


if判断,注意模板语言中的空格不能少
{% if row == "zhangs" %}
    <li>{{ row }}</li>
{% else %}
      <li>else 不需要end</li>
{% endif %}

获取字典或列表指定值
<a> {{ user_list.1 }}等同于list[1] </a><a> {{ user_dict.k1 等同于dict['k1']}} </a>
<a> {{ user_dict.k2 }} </a>
                        
for循环序号
{% for k in user_list %}
      {{ forloop.counter }}循环计数,默认从1开始forloop.counter0 从0开始
{{ forloop.revccounter }}倒排序54321 ,也有0属性
{{ forloop.first }} 循环的第一次,值为true
{{ forloop.last }} 循环的最后一次,值为true
{{ forloop.parentloop }} 父循环的次数,这个很少用
{% endfor %}


模板继承

母板:{% block title %}{% endblock %} 
子板:{% extends "base.html" %}   一个子版只能集成一个母板
   {% block title %}{% endblock %}

     {% include xxx.html %} 可以多个xxx.html,文件中也可以包含{{ 模板变量 }}

帮助方法:
{{ item.event_start|date:"Y-m-d H:i:s"}} 将参数转成日期输出
{{ bio|truncatewords:"30" }}             输出参数的前30个字节
{{ my_list|first|upper }}                输出开头大写,全部大写
{{ name|lower }}                         输小写

自定义tag实现上面帮助方法:

模板中的方法对我们来说还是比较少的,可以在某些情况下无法满足

1在app中创建templatetags文件夹,必须是这个名字

2创建任意 .py 文件

 1 #!/usr/bin/env python
 2 #coding:utf-8
 3 from django import template
 4 from django.utils.safestring import mark_safe
 5    
 6 #必须是register
 7 register = template.Library()
 8    
 9 @register.simple_tag
10 def my_simple_time(a,b):
11     return  a+b
12  
13 
14   
15 @register.simple_tag
16 def my_input(id,arg):
17     result = "<input type='text' id='%s' class='%s' />" %(id,arg,)
18     return mark_safe(result)
View Code

3在使用自定义simple_tag的html文件中导入之前创建的 xx.py 文件名

{% load xx %}

4使用tag

1 {% my_simple_time 1 2 %}
2 {% my_input 'id_username' 'hide'%}
View Code

filter,跟tags很像

#!/usr/bin/env python
#coding:utf-8
from django import template
from django.utils.safestring import mark_safe

register = template.Library()

#定义tag
@register.simple_tag
def add(p1,p2):
    return  p1 + p2

#定义filter
@register.filter()
def add2(p1,p2):
    return  p1 + p2

html页面

和上面定义的帮助方法一样,filter只能接受2个参数。如果想接受多个需要改源码{{ par|add2:"30,222,aa,sss" }}冒号后面的字符串分割。

{{ par|add2:"30" }}

filter有个一个作用就是可以用if 判断,tags是无法完成的

{% if  par1|add2:"33" %}
     .................
{% endif %}
 

 FBV & CBV
fba:function base view  

cbv:class base view  

2者区别就是一个用函数式一个用类

函数这里就不演示了,这里演示一下类

创建类的视图,view.py

 1 #导入模块1.8以上会有很多模板可以看看django.views.generic下的__init__.py
 2 #可以参考这个http://ccbv.co.uk/
 3 from django.views.generic import View
 4 #这个类必须继承view
 5 class Home(View):
 6     #方法:['get', 'post', 'put', 'patch', 'delete', 'head', 'options', 'trace']可以查看View方法
 7     #类名小写,类中会处理格式转换成小写,如果发的是get请求就执行这个方法
 8     def get(self,request):
 9         return HttpResponse("ok:get")
10     #如果发
11     def post(self,request):
12         return HttpResponse("ok:post")

url

1 增加一个url条目
2 url(r'^home/$', views.Home.as_view()),
urls.py

 django如何做到?

1 代码是view下的一个方法dispatch
2 def dispatch(self, request, *args, **kwargs):
3         #先把请求的方法转换成小写然后去对比方法列表是否存在
4         if request.method.lower() in self.http_method_names:
5             #这里就是利用了反射,方法列表中有就进行反射
6             handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
7         else:
8             handler = self.http_method_not_allowed
9         return handler(request, *args, **kwargs)

那用上面的代码来做些事情,上的方法可以在post、get等之前执行

 1 #-*- coding:utf-8  -*-
 2 from django.shortcuts import render,HttpResponse
 3 
 4 # Create your views here.
 5 from django.views.generic import View
 6 
 7 class Home(View):
 8     def dispatch(self, request, *args, **kwargs):
 9         #先执行一下父类方法
10         func=super(Home,self).dispatch(request, *args, **kwargs)
11         #将子串反给客户端,在这个中间就可以加上自己的一些处理了
12         #这里就可以完成装饰器的功能了
13         return func
14     def get(self,request):
15         return HttpResponse("ok:get")
16     #如果发
17     def post(self,request):
18         return HttpResponse("ok:post")
View Code

url匹配

这个是匹配的url
url(r'^detail-(d+)-(d+).html/$', views.detail)


#方法
def detail(request,sid,uid):

    return HttpResponse(sid+'/'+uid)


这个在访问上没有什么问题,但是如果底层方法把入口的sid和uid写反了的话结果就会不一样了。那如何避免?
url改成下面的即可,用正则分组来完成,这样一来不管底层入口函数如何变化都不会有影响了
url(r'^detail-(?P<sid>d+)-(?P<uid>d+).html/$', views.detail)

 

url路由名称

url(r'^index/$', views.index,name='index_page'),

现在把r'^index/$改成asdasdasd这个样子,前端就必须更改,比较麻烦。django已经把这个问题解决了就是加name参数


 <form action="{% url 'index_page' %}" method="POST" enctype="multipart/form-data">


表单中的url写成这样{% url 'index_page' %}  就OK了,不管urlsr'^index/$'如何改变都不会有影响了

加参数{% url 'index_page' 1 %}

获取当前url,当编辑一个页面后还想返回到编辑前的这个页面

request.path_info

命令空间

将不同的匹配指向相同的方法view

项目url

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^app01/',include('myapp.urls')),

   下面这二个就是命名空间了,相同的app,不同的匹配规则(a/b)对应不同的namespace
    url(r'^a/',include('myapp.urls',namespace='author-polls')),
    url(r'^b/',include('myapp.urls',namespace='publisher-polls')),
]

app url写法

这个必须要有
app_name='app01'
urlpatterns = [
url(r'^test/$', views.test,name='test'),必须要有name因为要reverse
]

view写法

def test(request):
    from django.core.urlresolvers import reverse
   #这里将namespace 的author-polls转成test url
    v=reverse('author-polls:test')
    print(v)
    return HttpResponse("Ok")

reverse反转一个url

urls
url(r'^index/(d+)$', views.index,name='index_page'),
url(r'^home/$', views.Home.as_view()),

方法,这个cbv或fbv都可以这里只是一个例子
class
Home(View): def get(self,request): #1.8之前这样导入from django.urls import reverse from django.core.urlresolvers import reverse
#第一个参数是name对应的名字 new_path
=reverse('index_page',args=(70,)) print(new_path) return HttpResponse(request.path_info)

总结url大致就三种

 1 对URL路由关系进行命名, ***** 以后可以根据此名称生成自己想要的URL *****
 2         
 3         url(r'^asdfasdfasdf/', views.index, name='i1'),
 4         url(r'^yug/(d+)/(d+)/', views.index, name='i2'),
 5         url(r'^buy/(?P<pid>d+)/(?P<nid>d+)/', views.index, name='i3'),
 6         
 7         
 8         
 9         def func(request, *args, **kwargs):
10             from django.urls import reverse
11             
12             url1 = reverse('i1')                              # asdfasdfasdf/
13             url2 = reverse('i2', args=(1,2,))                 # yug/1/2/
14             url3 = reverse('i3', kwargs={'pid': 1, "nid": 9}) # buy/1/9/
15         
16         
17         xxx.html
18             
19             {% url "i1" %}               # asdfasdfasdf/
20             {% url "i2" 1 2 %}           # yug/1/2/
21             {% url "i3" pid=1 nid=9 %}   # buy/1/9/
总结

路由分发,实现多级的urls转发

urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
#以app01开头的都转发到app01.urls去 url(r
'^app01/',include('app01.urls')), ]

orm基本操作

select * from tb where id > 1
# 对应关系
models.tb.objects.filter(id__gt=1)  大于__gt
models.tb.objects.filter(id=1)        等于 =
models.tb.objects.filter(id__lt=1)   小于__lt

#
def create_info(request):
    #第一种创建数据库的方法
    #自增长字段和自添加字段不需要写
    #id、modify_time、create_time
    # obj=models.CreateInfo.objects.create(
    #     user='wangj',
    #     email='asda@qq.com',
    #     pwd='123456',
    #     host_name='hadoop',
    #     system_type='生产系统',
    #     images_type='centosy7',
    #     apply_status='yes',
    #     flavor_type='4c_2g',
    # )
    #第二种创建用户信息
    # obj2=models.CreateInfo(user='mky',email='asd@1123.com',pwd='12345',host_name='hadoop',system_type='生产系统',images_type='centosy7',apply_status='yes',flavor_type='4c_2g')
    # obj2.save()

    #第三种创建用户信息,有点是第一种的变种利用字典方式
    create_dic={
        'user':'lisi',
        'email':'asda@qq.com',
        'pwd':'123456',
        'host_name':'hadoop',
        'system_type':'生产系统',
        'images_type':'centosy7',
        'apply_status':'yes',
        'flavor_type':'4c_2g',}
    obj=models.CreateInfo.objects.create(**create_dic)
    return HttpResponse("OK")

#
def select_info(request):
        #查询CreateInfo所有信息
        #obj=models.CreateInfo.objects.all()
        #queryset 是django自定义的一个类型。这个是个列表格式[obj1,obj2,obj3]里面存放对象
        #[<CreateInfo: CreateInfo object>, <CreateInfo: CreateInfo object>, <CreateInfo: CreateInfo object>]
        # print(obj)
        # for i in obj:
        #     print(i.user,i.email,i.flavor_type)
        #循环后的结果
        # (u'wangj', u'asda@qq.com', u'4c_2g')
        # (u'mky', u'asd@1123.com', u'4c_2g')
        # (u'lisi', u'asda@qq.com', u'4c_2g')

        #查询某个字段,如果可以重名那么这里就是多条.不管返回几条都是queryset 类型
        #obj=models.CreateInfo.objects.filter(user='mky')
        #obj=models.CreateInfo.objects.filter(user='mky',enail="asdas@qq.com")


        return HttpResponse(obj)

#删除
def delete_info(request):
    #删除表中所有数据
    #models.CreateInfo.objects.all().delete()
    #删除符合条件的数据
    models.CreateInfo.objects.filter(id=1).delete()

#更新
def update_info(request):
    #更新所有用户的pwd字段值为123456
    #models.CreateInfo.objects.all().update(pwd='123456')
    #指定用户更新
    models.CreateInfo.objects.filter(user='mky').update(pwd='123456')
基本增删改查

********** 注意 ***********
Django默认使用MySQLdb模块链接MySQL,py3中的mysql模块还没有。
主动修改为pymysql,在project同名文件夹下的__init__文件中添加如下代码即可:
import pymysql
pymysql.install_as_MySQLdb()

类型介绍

  1 AutoField(Field)
  2         - int自增列,必须填入参数 primary_key=True
  3 
  4     BigAutoField(AutoField)
  5         - bigint自增列,必须填入参数 primary_key=True
  6 
  7         注:当model中如果没有自增列,则自动会创建一个列名为id的列
  8         from django.db import models
  9 
 10         class UserInfo(models.Model):
 11             # 自动创建一个列名为id的且为自增的整数列
 12             username = models.CharField(max_length=32)
 13 
 14         class Group(models.Model):
 15             # 自定义自增列
 16             nid = models.AutoField(primary_key=True)
 17             name = models.CharField(max_length=32)
 18 
 19     SmallIntegerField(IntegerField):
 20         - 小整数 -32768 ~ 32767
 21 
 22     PositiveSmallIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
 23         - 正小整数 0 ~ 32767
 24     IntegerField(Field)
 25         - 整数列(有符号的) -2147483648 ~ 2147483647
 26 
 27     PositiveIntegerField(PositiveIntegerRelDbTypeMixin, IntegerField)
 28         - 正整数 0 ~ 2147483647
 29 
 30     BigIntegerField(IntegerField):
 31         - 长整型(有符号的) -9223372036854775808 ~ 9223372036854775807
 32 
 33     自定义无符号整数字段
 34 
 35         class UnsignedIntegerField(models.IntegerField):
 36             def db_type(self, connection):
 37                 return 'integer UNSIGNED'
 38 
 39         PS: 返回值为字段在数据库中的属性,Django字段默认的值为:
 40             'AutoField': 'integer AUTO_INCREMENT',
 41             'BigAutoField': 'bigint AUTO_INCREMENT',
 42             'BinaryField': 'longblob',
 43             'BooleanField': 'bool',
 44             'CharField': 'varchar(%(max_length)s)',
 45             'CommaSeparatedIntegerField': 'varchar(%(max_length)s)',
 46             'DateField': 'date',
 47             'DateTimeField': 'datetime',
 48             'DecimalField': 'numeric(%(max_digits)s, %(decimal_places)s)',
 49             'DurationField': 'bigint',
 50             'FileField': 'varchar(%(max_length)s)',
 51             'FilePathField': 'varchar(%(max_length)s)',
 52             'FloatField': 'double precision',
 53             'IntegerField': 'integer',
 54             'BigIntegerField': 'bigint',
 55             'IPAddressField': 'char(15)',
 56             'GenericIPAddressField': 'char(39)',
 57             'NullBooleanField': 'bool',
 58             'OneToOneField': 'integer',
 59             'PositiveIntegerField': 'integer UNSIGNED',
 60             'PositiveSmallIntegerField': 'smallint UNSIGNED',
 61             'SlugField': 'varchar(%(max_length)s)',
 62             'SmallIntegerField': 'smallint',
 63             'TextField': 'longtext',
 64             'TimeField': 'time',
 65             'UUIDField': 'char(32)',
 66 
 67     BooleanField(Field)
 68         - 布尔值类型
 69 
 70     NullBooleanField(Field):
 71         - 可以为空的布尔值
 72 
 73     CharField(Field)
 74         - 字符类型
 75         - 必须提供max_length参数, max_length表示字符长度
 76 
 77     TextField(Field)
 78         - 文本类型
 79 
 80     EmailField(CharField):
 81         - 字符串类型,Django Admin以及ModelForm中提供验证机制
 82 
 83     IPAddressField(Field)
 84         - 字符串类型,Django Admin以及ModelForm中提供验证 IPV4 机制
 85 
 86     GenericIPAddressField(Field)
 87         - 字符串类型,Django Admin以及ModelForm中提供验证 Ipv4和Ipv6
 88         - 参数:
 89             protocol,用于指定Ipv4或Ipv6, 'both',"ipv4","ipv6"
 90             unpack_ipv4, 如果指定为True,则输入::ffff:192.0.2.1时候,可解析为192.0.2.1,开启刺功能,需要protocol="both"
 91 
 92     URLField(CharField)
 93         - 字符串类型,Django Admin以及ModelForm中提供验证 URL
 94 
 95     SlugField(CharField)
 96         - 字符串类型,Django Admin以及ModelForm中提供验证支持 字母、数字、下划线、连接符(减号)
 97 
 98     CommaSeparatedIntegerField(CharField)
 99         - 字符串类型,格式必须为逗号分割的数字
100 
101     UUIDField(Field)
102         - 字符串类型,Django Admin以及ModelForm中提供对UUID格式的验证
103 
104     FilePathField(Field)
105         - 字符串,Django Admin以及ModelForm中提供读取文件夹下文件的功能
106         - 参数:
107                 path,                      文件夹路径
108                 match=None,                正则匹配
109                 recursive=False,           递归下面的文件夹
110                 allow_files=True,          允许文件
111                 allow_folders=False,       允许文件夹
112 
113     FileField(Field)
114         - 字符串,路径保存在数据库,文件上传到指定目录
115         - 参数:
116             upload_to = ""      上传文件的保存路径
117             storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
118 
119     ImageField(FileField)
120         - 字符串,路径保存在数据库,文件上传到指定目录
121         - 参数:
122             upload_to = ""      上传文件的保存路径
123             storage = None      存储组件,默认django.core.files.storage.FileSystemStorage
124             width_field=None,   上传图片的高度保存的数据库字段名(字符串)
125             height_field=None   上传图片的宽度保存的数据库字段名(字符串)
126 
127     DateTimeField(DateField)
128         - 日期+时间格式 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]
129 
130     DateField(DateTimeCheckMixin, Field)
131         - 日期格式      YYYY-MM-DD
132 
133     TimeField(DateTimeCheckMixin, Field)
134         - 时间格式      HH:MM[:ss[.uuuuuu]]
135 
136     DurationField(Field)
137         - 长整数,时间间隔,数据库中按照bigint存储,ORM中获取的值为datetime.timedelta类型
138 
139     FloatField(Field)
140         - 浮点型
141 
142     DecimalField(Field)
143         - 10进制小数
144         - 参数:
145             max_digits,小数总长度
146             decimal_places,小数位长度
147 
148     BinaryField(Field)
149         - 二进制类型
150 
151 字段
类型

字段参数

 1 null                数据库中字段是否可以为空
 2     db_column           数据库中字段的列名
 3     db_tablespace
 4     default             数据库中字段的默认值
 5     primary_key         数据库中字段是否为主键
 6     db_index            数据库中字段是否可以建立索引
 7     unique              数据库中字段是否可以建立唯一索引
 8     unique_for_date     数据库中字段【日期】部分是否可以建立唯一索引
 9     unique_for_month    数据库中字段【月】部分是否可以建立唯一索引
10     unique_for_year     数据库中字段【年】部分是否可以建立唯一索引
11 
12     verbose_name        Admin中显示的字段名称
13     blank               Admin中是否允许用户输入为空
14     editable            Admin中是否可以编辑
15     help_text           Admin中该字段的提示信息
16     choices             Admin中显示选择框的内容,用不变动的数据放在内存中从而避免跨表操作
17                         如:gf = models.IntegerField(choices=[(0, '何穗'),(1, '大表姐'),],default=1)
18 
19     error_messages      自定义错误信息(字典类型),从而定制想要显示的错误信息;
20                         字典健:null, blank, invalid, invalid_choice, unique, and unique_for_date
21                         如:{'null': "不能为空.", 'invalid': '格式错误'}
22 
23     validators          自定义错误验证(列表类型),从而定制想要的验证规则
24                         from django.core.validators import RegexValidator
25                         from django.core.validators import EmailValidator,URLValidator,DecimalValidator,
26                         MaxLengthValidator,MinLengthValidator,MaxValueValidator,MinValueValidator
27                         如:
28                             test = models.CharField(
29                                 max_length=32,
30                                 error_messages={
31                                     'c1': '优先错信息1',
32                                     'c2': '优先错信息2',
33                                     'c3': '优先错信息3',
34                                 },
35                                 validators=[
36                                     RegexValidator(regex='root_d+', message='错误了', code='c1'),
37                                     RegexValidator(regex='root_112233d+', message='又错误了', code='c2'),
38                                     EmailValidator(message='又错误了', code='c3'), ]
39                             )
40 
41 参数
参数

外键ForeignKey一对多

# Create your models here.
class UserGroup(models.Model):
    #自增列必须加主键
    uid = models.AutoField(primary_key=True)
    caption = models.CharField(max_length=32)

class UserInfo(models.Model):
    username=models.CharField(max_length=16,verbose_name='用户名',help_text='django中的提示信息')
    password=models.CharField(max_length=60)
    email= models.EmailField(max_length=16)
    #运行中放在内存中,并没有放在表中,这个在django admin中提示下拉框选项,避免链表查询
    user_type_id=(
        (1,'管理员'),
        (2,'普通用户'),
    )
    user_type=models.IntegerField(choices=user_type_id,default=1)
    #to_field指定外键关联的字段,必须唯一。也可以不指定默认选择主键
    user_group=models.ForeignKey('UserGroup',to_field='uid')

总结:

 1 一对多:
 2         
 3             a. 外键
 4             b. 外键字段_id
 5                                 #增加外键的值,这样直接增加比较方便
 6             c.    models.tb.object.create(name='root', user_group_id=1)
 7                 
 8             d.     userlist = models.tb.object.all()
 9                 for row in userlist:
10                     row.id
11                                         循环外键表的属性
12                     row.user_group_id
13                     row.user_group.caption
总结

查询总结,objects.all()、values、values_list

1 def business(request):
2     #获取所有对象,objv1 是queryset 类型返回对象[obj,ob,obj]
3     objv1=models.Business.objects.all()
4 
5     #values等同于 select id,caption from business.  objv2 是queryset 类型返回字典['k1':'k2','k3':'k4']
6     objv2=models.Business.objects.all().values("id","caption")
7 
8     #objv2 是queryset 类型返回元组[(1,"市场"),(2,"业务")]
9     objv3=models.Business.objects.all().values_list("id","caption")
view
 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>Title</title>
 6 </head>
 7 <body>
 8   <h1>业务线列表(objv1对象)</h1>
 9   <ul>
10       {% for i in objv1 %}
11           <li>{{ i.id }}-{{ i.caption }}-{{ i.code }}</li>
12       {% endfor %}
13   </ul>
14    <h1>业务线列表(objv2字典)</h1>
15   <ul>
16       {% for i in objv2 %}
17           <li>{{ i.id }}-{{ i.caption }}</li>
18       {% endfor %}
19   </ul>
20  <h1>业务线列表(objv3元组)</h1>
21   <ul>
22       {% for i in objv3 %}
23           <li>{{ i.0 }}-{{ i.1 }}</li>
24       {% endfor %}
25   </ul>
26 </body>
27 </html>
模板

跨表操作

def host(request):
    v1=models.Host.objects.all()
    for i in v1:
        #跨表获取数据i.b_id,i.b.caption,i.b.code,跨表查询以"点"获取
        print(i.nid,i.hostname,i.ip,i.port,i.b_id,i.b.caption,i.b.code)
    #跨表打印数据
    print(v1[1].b.caption)
    #values跨表查询,必须用双下划线"__"来代替上面的"点"。里面是[{k:v}]
    v2=models.Host.objects.all().values('nid','b__caption','b__code')
    for i in v2:
#这里可以看出上面values中的字段都是下面的key,在前端也是如此
#前端i['nid'],i['b__caption'],i['b__code']
print(i['nid'],i['b__caption'],i['b__code'])

#values_list返回的元组
v3=models.Host.objects.all().values_list('nid','b__caption','b__code')
    for i in v2:
#因为返回的元组,所以这里必须用索引来取值,前端也是。
#前端例子 {{i.1}}
print(i[0],i[1],i[2])
return HttpResponse("OK")
原文地址:https://www.cnblogs.com/menkeyi/p/6819016.html