type python django models_Python菜鸟之路:Django 路由、模板、Model(ORM)

Django路由系统

Django的路由系统让Django可以根据URI进行匹配,进而发送至特定的函数去处理用户请求。有点类似nginx的location功能。

Django的路由关系分为三种:普通关系、动态关系、分组分发。这三种关系都记录在urls.py中。

路由-普通关系

普通关系表示一个url对应一个函数,例如:

urlpatterns = [

url(r'^admin/', admin.site.urls),

url(r'^login/', views.login),

url(r'^detail/', views.detail),

]

路由-动态关系

动态关系表示通过正则的方式去实现动态匹配。例如:

urlpatterns = [

url(r'^detail/(\d+)/', views.detail), # 动态路由之:单参数的路由

url(r'^detail2/(\d+)/', views.detail2), # 动态路由之:多参数的路由

url(r'^detail3/(?P\d+)/(?P\d+)/', views.detail3), # 动态路由之:命名参数,两个参数分别被命名为p1和x2

url(r'^index/(\d+)/', views.index), # 分页显示

]

动态路由,也是动态关系的一种,动态路由其实通过映射也可以实现,需要自己来实现

主要代码实现1、url.py

配置url映射2、activator.py

根据url中获取的参数,通过反射调用指定 app/view.py 中的函数

如:

http://127.0.0.1:9000/app01/index/ ==》 执行app01/view.py文件中的index函数

http://127.0.0.1:9000/app02/index/ ==》 执行app02/view.py文件中的index函数

http://127.0.0.1:9000/app01/login/ ==》 执行app01/view.py文件中的login函数#具体代码:#总入口urls.py

from django.conf.urls importinclude, urlfrom django.contrib importadminfrom DynamicRouter.activator importprocess

urlpatterns=[#Examples:

#url(r'^$', 'DynamicRouter.views.home', name='home'),

#url(r'^blog/', include('blog.urls')),

url(r'^admin/', include(admin.site.urls)),

('^(?P(\w+))/(?P(\w+))/(?P(\d+))/(?P(\d+))/$',process),

('^(?P(\w+))/(?P(\w+))/(?P(\d+))/$',process),

('^(?P(\w+))/(?P(\w+))/$',process),

('^(?P(\w+))/$',process,{'function':'index'}),

]#activator.py代码

from django.shortcuts importrender_to_response,HttpResponse,redirectdef process(request,**kwargs):'''接收所有匹配url的请求,根据请求url中的参数,通过反射动态指定view中的方法'''app= kwargs.get('app',None)

function= kwargs.get('function',None)try:

appObj= __import__("%s.views" %app)

viewObj= getattr(appObj, 'views')

funcObj=getattr(viewObj, function)#执行view.py中的函数,并获取其返回值

result =funcObj(request,kwargs)except(ImportError,AttributeError) as e:#导入失败时,自定义404错误

return HttpResponse('404 Not Found')exceptException as e:#代码执行异常时,自动跳转到指定页面

return redirect('/app01/index/')return result

通过映射实现动态路由

路由-分组分发

什么是分组分发?一个Django项目里,通常会有很多的app,比如一些bbs论坛为例,他的项目里就有前端部分,供普通用户使用,这类url通常写作http://hostname/common/form.php 。 也有后端admin管理员部分,用来进行用户管理、帖子管理等功能。这类url通常有个特别,一般是http://hostname/admin/XXX。可以明显看到,这个论坛项目中,就有2个分组:common和admin。Django中也有这样的功能。

Django分组写法:

步骤1:导入include函数

from django.conf.urls import include

步骤2:创建url映射

urlpatterns = [

...

url(r'^common/', include("frontweb.urls")), # 多app项目的分组匹配

url(r'^admin/', include("manager.urls")), # 多app项目的分组匹配

]

上面代码中,定义了2个app,一个是frontweb,一个是manager。

步骤3:在app中创建对应的url

# manager\urls.py中 代码

from manager import views

urlpatterns = [

url(r'^assets', views.assets),

url(r'^userinfo', views.userinfo),

]

# frontweb\urls.py中 代码

from frontweb import views

urlpatterns = [

url(r'^index/(\d+)/', views.index),

url(r'^detail/(\d+)/', views.detail),

url(r'^userinfo', views.userinfo),

]

模板

模版的创建过程,对于模版,其实就是读取模版(其中嵌套着模版标签),然后将 Model 中获取的数据插入到模版中,最后将信息返回给用户。

模板的语法

1. 传普通字符串

# python中

return render(request, 'index.html', {'k1': 'v1'})

# html中引用k1的值

{{ k1 }}

2. 传入列表

# python中

return render(request, 'index.html', {'k2': [11,22,33,44]})

# html中引用k1的值

{{ k2 }}

{{ k2.0 }}

{{ k2.1 }}

{{ k2.2 }}

3. 传入字典

# python中

return render(request, 'index.html', {'k3': {'name': 'Bob', 'nid': 18}})

# html中引用k1的值

{{ k3 }}

{{ k3.name }}

{{ k3.nid}}

4. 模板中的for循环,还是以上边的传入列表k2为例

{% for item in k2 %}

{{ item }},

{{ forloop.counter }},

{{ forloop.counter0 }},

{{ forloop.first }},

{{ forloop.last }},

{{ forloop.revcounter }}

{% endfor %}

5. 模板中的if循环,以上边传入的k1为例

{% if k1 == 'v1' %}

V1

{% elif k1 == 'v2' %}

V2

{% else %}

777777

{% endif %}

6. 模板中的继承语法

母板:{% block title %}{% endblock %}

子板:{% extends "base.html" %}

{% block title %}{% endblock %}

7. 模板内置的一些方法(可以理解为函数,而模板中的变量就是传入的值)

{{ item.event_start|date:"Y-m-d H:i:s"}}

{{ bio|truncatewords:"30" }}

{{ my_list|first|upper }}

{{ name|lower }}

8. 自定义模板方法

自定义模板方法,有两种方式,一种是filter,另外一种是simple_tag

8.1 filter

步骤1:创建指定文件夹,名称必须为templatetags,文件夹放在对应的app目录下。

步骤2:创建任意的py文件,比如xx.py

from django import template

from django.utils.safestring import mark_safe

from django.template.base import Variable, Node, TemplateSyntaxError

register = template.Library()

#要点1: template.Library的返回值的变量,必须是register,不能是其他

#要点2:函数必须加装饰器register.filter,这样f1就是模板语言中的一个函数

@register.filter

def f1(value):

# 接收单个参数

return value + 'f111'

@register.filter

def f2(value, value2):

# 接收两个参数

return value + value2

步骤3:使用函数,在html模板的头部,执行{% load xx %},xx表示创建的py文件的文件名

{% load xx %}

步骤4:使用函数

# html中代码

{{ k1|f1 }} {# filter自定义方法之:1个参数 #}

# 输出 v1f111 # 其中v1是k1本身的值,f111是函数后加的字符串

# html中代码

{{ k1|f2:'F2:XXX' }}
{# filter自定义方法之:2个参数 #}

{% if k1|f1 == 'v1f111' %}

filter可以用作if语句的条件

{% endif %}

最终输出: v1F2:XXX 其中v1是k1的值, F2:XXX是前端传入的变量

Ps:从上边可以看出,filter方法构建的函数,默认不支持传入超过2个以上的参数,因此,如果需要传入多个参数,可以将"F2:XXX"写成 "F2:XXX,arg3,arg4",在python代码中,用split来拆分字符串,来获取参数。

限制:传参个数有限制,多个参数需要自行split进行切割

支持:可以作为模板中if语句的if条件

步骤5:注册app。最后一步非常重要,否则django会不知道去哪个路径下查找xx.py。

# 在settings.py中注册app

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'app01', # 新注册的app目录名称

]

8.2 用simple_tag 来自定义模板方法

创建simple_tag的步骤基本一致,唯独不同的有2个地方

不同点1: 函数的装饰器需要写为register.simple_tag

@register.simple_tag

def f3(value):

return value + 'f3333'

@register.simple_tag

def f4(value, arg1, arg2):

return value + arg1 + arg2

不同点2:前端html传参的时候

# html中的代码

{% f3 'simple_tag' %}
{# simple_tag自定义方法之:1个参数 #}

{% f4 'simple_tag' 'arg2' 'arg3' %}
{# simple_tag自定义方法之:多个参数 #}

# 输出

simple_tagf3333

simple_tagarg2arg3

Ps:用simple_tag来创建函数,不支持作为if语句中的条件

模板的渲染过程

看一张图就明白,

模板继承

母版页面

母版页面通常用来定义网页的基本框架结构,同时空出部分内容块来供子页面来自定义式的填充

# 母版的代码

{% block css %}{% endblock %} # 空出名为css的代码块部分,供子版来填充

{% block body %}{% endblock %} # 同上,只是名称不同而已

{% block js %}{% endblock %} #同上,只是名称不同而已

完整代码示例如下图:

子页面

{% extends 'layout.html' %} # 表示继承layoout.html母版页面

{% block css %} #自定义样式

...

{% endblock %}

{% block body %} # 填充html内容

{% for item in assets_list %}

{{ item.hostname }}{{ item.port }}

{% endfor %}

{% endblock %}

{% block js %} # 自定义js

...

{% endblock %}

重复利用的小插件

一般情况下,在页面中,会有一些元素是相似度很高的,或许只有装饰文件不同而已。比如京东首页中,家电数码、个性美妆、手机通讯等部分。通常的做法是把这些相似的部分,做成类似小插件一样的html代码,在使用的时候引用即可。

{% include "xx.html" %}

Django中的Model

在Django的model中,提供了两类操作,一种是创建数据库表(CURD),一种是操作数据库的数据

Django数据库表间的三种关系

Django的数据库表中,有三种关系:一对一,一对多,多对多。

假设有两张表userinfo和user_type 。

class userinfo(models.Model):

nid = models.AutoField(primary_key=True)

name = models.CharField(max_length=30, verbose_name='用户名',editable=TabError)

email = models.EmailField(db_index=True)

memo = models.TextField()

# 普通用户,超级用户

class UserType(models.Model):

name = models.CharField(max_length=32)

def __str__(self):

return self.name

一对一

即 user_type = OneToOneField("另外一张表")

这种情况下,每次创建一条userinfo数据,就需要userType表中一条数据与之对应。即,usertype表中的数据,只能被对应一次。

一对多

即 user_type = models.ForeignKey("UserType")

这是很常见的一种对应关系。比如一个usertype有两种用户,超级用户和普通用户,那么在这两种用户组中,可以分别存在很多人。

多对多

即 user_type = models.ManyToManyField("UserType")。

比如,一个user可以属于多个usergroup,一个usergroup可以包含多个user,这就是典型的多对多关系。

创建数据库表

步骤1:在app的models.py中写类,来创建表的每个字段

1、models.AutoField  自增列 = int(11)

如果没有的话,默认会生成一个名称为 id 的列,如果要显示的自定义一个自增列,必须将给列设置为主键 primary_key=True。2、models.CharField  字符串字段

必须 max_length 参数3、models.BooleanField  布尔类型=tinyint(1)

不能为空,Blank=True4、models.ComaSeparatedIntegerField  用逗号分割的数字=varchar

继承CharField,所以必须 max_lenght 参数5、models.DateField  日期类型 date

对于参数,auto_now=True 则每次更新都会更新这个时间;auto_now_add 则只是第一次创建添加,之后的更新不再改变。6、models.DateTimeField  日期类型 datetime

同DateField的参数7、models.Decimal  十进制小数类型 =decimal

必须指定整数位max_digits和小数位decimal_places8、models.EmailField  字符串类型(正则表达式邮箱) =varchar

对字符串进行正则表达式9、models.FloatField  浮点类型 =double10、models.IntegerField  整形11、models.BigIntegerField  长整形

integer_field_ranges={'SmallIntegerField': (-32768, 32767),'IntegerField': (-2147483648, 2147483647),'BigIntegerField': (-9223372036854775808, 9223372036854775807),'PositiveSmallIntegerField': (0, 32767),'PositiveIntegerField': (0, 2147483647),

}12、models.IPAddressField  字符串类型(ip4正则表达式,在1.10的django版本中,可能会被替换掉,统一使用models.GenericIPAddressField)13、models.GenericIPAddressField  字符串类型(ip4和ip6是可选的)

参数protocol可以是:both、ipv4、ipv6

验证时,会根据设置报错14、models.NullBooleanField  允许为空的布尔类型15、models.PositiveIntegerFiel  正Integer16、models.PositiveSmallIntegerField  正smallInteger17、models.SlugField  减号、下划线、字母、数字18、models.SmallIntegerField  数字

数据库中的字段有:tinyint、smallint、int、bigint19、models.TextField  字符串=longtext20、models.TimeField  时间 HH:MM[:ss[.uuuuuu]]21、models.URLField  字符串,地址正则表达式22、models.BinaryField  二进制23、models.ImageField 图片(以字符串形式保存,存储文件路径)24、models.FilePathField 文件(以字符串形式保存,存储文件路径)

models中的字段类型

1、null=True

数据库中字段是否可以为空2、blank=True

django的 Admin 中添加数据时是否可允许空值3、primary_key =False

主键,对AutoField设置主键后,就会代替原来的自增 id 列4、auto_now 和 auto_now_add

auto_now 自动创建---无论添加或修改,都是当前操作的时间

auto_now_add 自动创建---永远是创建时的时间5、choices

GENDER_CHOICE=(

(u'M', u'Male'),

(u'F', u'Female'),

)

gender= models.CharField(max_length=2,choices =GENDER_CHOICE)6、max_length7、default  默认值8、verbose_name  Admin中字段的显示名称9、name|db_column  数据库中的字段名称10、unique=True  不允许重复11、db_index =True  数据库索引12、editable=True  在Admin里是否可编辑13、error_messages=None  错误提示14、auto_created=False  自动创建15、help_text  在Admin中提示帮助信息16、validators=[]17、upload-to

models中字段类型的可选参数

步骤2:执行python manager.py makemigrations && python manager.py migrate初始化数据库结构

操作数据库表-基本操作

基本数据访问

运行python manage.py shell并使用Django提供的高级Python API

# 导入student模型类,通过这个类我们可以与student数据表进行交互

>>> from app01.models import UserType

# 创建一个student类的实例并设置了字段name的值

>>> data_1 = UserType(name='外围人员')

# 调用该对象的save()方法,将对象保存到数据库中,Django会在后台执行一条INSERT语句

>>> s1.save()

# 再插入一条数据

>>> data_2 = UserType(name='核心人员')

>>> data_2 .save()

# 使用UserType.objects属性从数据库取出UserType表的记录集,这个属性有许多方法,UserType.objects.all()方法获取数据库中UserType类的所有对象,实际上Django执行了一条SQL SELECT语句

>>> usertype_list = UserType.objects.all()

>>> usertype_list

Out[6]: , , ]>

在代码中进行数据访问基本操作

方法1:

models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs

方法2:

obj = models.Tb1(c1='xx', c2='oo')

obj.save()

models.Tb1.objects.filter(name='seven').delete() # 删除指定条件的数据

方法1:

models.Tb1.objects.filter(name='seven').update(gender='0') # 将指定条件的数据更新,均支持 **kwargs

方法2:

obj = models.Tb1.objects.get(id=1)

obj.c1 = '111'

obj.save() # 修改单条数据

models.Tb1.objects.get(id=123) # 获取单条数据,不存在则报错(不建议)

models.Tb1.objects.all() # 获取全部

models.Tb1.objects.filter(name='seven') # 获取指定条件的数据

obj = model.UserInfo.objects.filter(name='alex').values('id','email')

#sql: select id,email from userinfo where name = 'alex'

# 结果是个字典:[{'id':1 , 'email':'xxq@qq.com'}, {'id':2 , 'email':'qqqq@qq.com'},...]

obj = model.UserInfo.objects.filter(name='alex').value_list('id','email')

#sql: select id,email from userinfo where name = 'alex'

#结果是个元祖 [('1', 'xxq@qq.com'), ('2', 'qqq@qq.com'), (),....]

说明

执行models.Tb1.objects.all()等查询的结果,是一个queryset对象,而queryset是Django中定义的一个类

操作数据库单表-进阶操作

#获取个数#

#models.Tb1.objects.filter(name='seven').count()

#大于,小于---gt lt语句#

#models.Tb1.objects.filter(id__gt=1) # 获取id大于1的值#models.Tb1.objects.filter(id__lt=10) # 获取id小于10的值#models.Tb1.objects.filter(id__lt=10, id__gt=1) # 获取id大于1 且 小于10的值

#in#

#models.Tb1.objects.filter(id__in=[11, 22, 33]) # 获取id等于11、22、33的数据#models.Tb1.objects.exclude(id__in=[11, 22, 33]) # not in

#contains---like语句#

#models.Tb1.objects.filter(name__contains="ven") # contains就是like#models.Tb1.objects.filter(name__icontains="ven") # icontains 表示对大小写不敏感#models.Tb1.objects.exclude(name__icontains="ven")

#range ---between and语句#

#models.Tb1.objects.filter(id__range=[1, 2]) # 范围bettwen and

#其他类似#

#startswith,istartswith, endswith, iendswith,

#order by#

#models.Tb1.objects.filter(name='seven').order_by('id') # asc#models.Tb1.objects.filter(name='seven').order_by('-id') # desc 加上负号表示倒序

#limit 、offset#

#models.Tb1.objects.all()[10:20] # 分页获取

#group by

from django.db.models importCount, Min, Max, Sum#models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num')) # 这里的value表示要根据id 进行groupby, 获取num列的个数#SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

单表进阶操作-了不起的双下划线

操作数据库连表-进阶操作

双下划线的主要功能:1)大于小于等操作,参照上面的单表进阶操作    2)跨表操作

数据库结构说明:

classUserProfile(models.Model):

user_info= models.OneToOneField('UserInfo')

username= models.CharField(max_length=64)

password= models.CharField(max_length=64)def __unicode__(self):returnself.usernameclassUserInfo(models.Model):

user_type_choice=(

(0, u'普通用户'),

(1, u'高级用户'),

)

user_type= models.IntegerField(choices=user_type_choice)

name= models.CharField(max_length=32)

email= models.CharField(max_length=32)

address= models.CharField(max_length=128)def __unicode__(self):returnself.nameclassUserGroup(models.Model):

caption= models.CharField(max_length=64)

user_info= models.ManyToManyField('UserInfo')def __unicode__(self):returnself.captionclassHost(models.Model):

hostname= models.CharField(max_length=64)

ip=models.GenericIPAddressField()

user_group= models.ForeignKey('UserGroup')def __unicode__(self):return self.hostname

数据库表结构

操作数据库联表-双下划线跨表查询

两种表的联表查询案例

#表结构

classUserInfo(models.Model):

user= models.CharField(max_length=32)

pwd= models.CharField(max_length=32)classUserInfo(models.Model):

user= models.CharField(max_length=32)

pwd= models.CharField(max_length=32)

user_type= models.ForignKey('UserType')#创建UserInfo

1、UserInfo.objects.create(user='alex',pwd='123',user_type=UserType.objects.get(id=2)) #这种方法不推荐,实际查询了2次

2、 UserInfo.objects.create(user='alex',pwd='123',user_type_id=2) #推荐这种方法!!!这种是进阶用法

#普通查询:

UserInfo.objects.filter(user='alex')1、查询所有用户类型等于 普通用户 的所有用户名和密码(普通查询方法)

uid= UserType.objects.get(caption='普通用户').id #uid是一个对象

UserInfo.objects.filter(user_type_id=uid)#进阶跨表查询方法及取值方法

querset = UserInfo.objects.filter(user_type__caption='普通用户')

querset= UserInfo.objects.filter(user_type__id__gt=2)

【UserInfo对象,UserInfo对象,UserInfo对象,】

row=querset[0]

row.user

row.pwd

row.user_type.id

row.user_type.caption#在进行models.object.xxx查询时,使用: objects __#获取到某一样的对象后使用: row.外键字段.外键表的字段

#使用values和value_list跨表查询方法及取值

querset = UserInfo.objects.filter(user_type__caption='普通用户').values('user','user_type__caption')

【{'user': 'alex','user_type__caption': '普通用户'},{'user': 'eric','user_type__caption': '普通用户'},】 结果是一个字典对象形成的列表#取出单值

row =querset[0]

row['user']

row['user_type__caption']

2张表的联表创建及查询

三张表跨表操作classSomthing(models.Model):

name= models.CharField(max_length=32)classUserType(models.Model):

catption= models.CharField(max_length=32)

s= models.ForignKey('Somthing')#超级管理员,普通用户,游客,黑河

classUserInfo(models.Model):

user= models.CharField(max_length=32)

pwd= models.CharField(max_length=32)

user_type= models.ForignKey('UserType')#通过Userinfo表,查询Something表中name是xx

UserInfo.objects.filter(user_type__s__name='xx')#多个下滑连通过外键__ 则可以

3张表的联表查询

Model中的多对多操作补充

Django中创建多对多关系有两种方式:

方式1:手动创建第三张表,与其他两张表建立外键关系

class B2G(models.Model):

b_id = models.ForeignKey('Boy')

g_id = models.ForeignKey('Girl')

class Boy(models.Model):

username = models.CharField(max_length=16)

def __str__(self):

return str(self.id)

class Girl(models.Model):

name = models.CharField(max_length=16)

def __str__(self):

return str(self.id)

方式2:利用models.ManyToManyField来让django自动创建第三张表

class Boy(models.Model):

username = models.CharField(max_length=16)

def __str__(self):

return str(self.id)

class Girl(models.Model):

name = models.CharField(max_length=16)

b = models.ManyToManyField('Boy')

def __str__(self):

return str(self.id)

多对多基本操作

建立两张表的关系:即向第三张表中增加数据-获取两个对象,通过add方法建立关系

########### 增加数据 ###########

# 获取一个女孩对象

g1 = models.Girl.objects.get(id=1)

# 获取一个男孩对象

b1 = models.Boy.objects.get(id=1)

# 利用多对多字段“b”将男孩和女孩建立关系--一对一建立关系

g1.b.add(models.Boy.objects.get(id=1))

g1.b.add(1) # 也可以传入数字或者 数字列表*【1,2,3】

# 添加和女孩1和 男孩1,2,3,4关联--一对多建立关系

g1 = models.Girl.objects.get(id=1)

g1.b.add(*[1,2,3,4])

# 将多个boy与女孩1建立关联

# boys = models.Boy.objects.all()

# g1.b.add(*boys)

查询数据

# 获取一个女孩对象

g1 = models.Girl.objects.get(id=1)

# 获取和当前女孩有关系的所有男孩

boy_list = g1.b.all()

print(boy_list)

删除数据

# 删除第三张表中和女孩1关联的所有关联信息

g1 = models.Girl.objects.get(id=1)

g1.b.clear()

# 删除女孩1和男孩2,3的关联

g1 = models.Girl.objects.get(id=1)

g1.b.remove(*[2,3])

特别补充——反向添加:由于manytomany的存在,在Boy表中,还有一个隐含字段girl_set,他的作用与Gril中的b字段是一样的功能。

b1 = models.Boy.objects.get(id=1)

b1.girl_set.add(1)

b1.girl_set.add(models.Girl.objects.all())

b1.girl_set.add(*[1,2,3,4])

多对多跨表操作

首先要明白一点,通过第三张表进行跨表操作,是通过left outer join的形式进行查询的,on的条件就是A表的id与B表的id相等。

# 两张表关联查询

models.Girl.objects.all().values('id','name', 'b')

# 查询 第三张表b的 girl.id==b.id的 b.boy_id列

SQL:

SELECT "app01_girl"."id", "app01_girl"."name", "app01_girl_b"."boy_id" FROM "app01_girl" LEFT OUTER JOIN "app01_girl_b" ON ("app01_girl"."id" = "app01_girl_b"."girl_id")

# 三张表关联查询-跨表查询

models.Girl.objects.all().values('id','name', 'b__username')

SQL:

SELECT "app01_girl"."id", "app01_girl"."name", "app01_boy"."username" FROM "app01_girl" LEFT OUTER JOIN "app01_girl_b" ON ("app01_girl"."id" = "app01_girl_b"."girl_id") LEFT OUTER JOIN "app01_boy" ON ("app01_girl_

b"."boy_id" = "app01_boy"."id")

r = models.Boy.objects.exclude(girl__name=None).values('id','username', 'girl__name')

print(r)

print(r.query)

#SELECT "app01_boy"."id", "app01_boy"."username", "app01_girl"."name" FROM "app01_boy" LEFT OUTER JOIN "app01_girl_b" ON ("app01_boy"."id" = "app01_girl_b"."boy_id") LEFT OUTER JOIN "app01_girl" ON ("app01_girl_b".

#"girl_id" = "app01_girl"."id") WHERE NOT ("app01_boy"."id" IN (SELECT U0."id" AS Col1 FROM "app01_boy" U0 LEFT OUTER JOIN "app01_girl_b" U1 ON (U0."id" = U1."boy_id") LEFT OUTER JOIN "app01_girl" U2 ON (U1."girl_i

#d" = U2."id") WHERE U2."name" IS NULL))

原生SQL操作-更新

在Django的SQL ORM框架中,对于更新操作的支持并不好,因此需要借助原生的sql语句来完成更新操作

from django.db import connection

cursor = connection.cursor()

cursor.execute("""SELECT * from tb where name = %s""", ['Lennon'])

row = cursor.fetchone()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牙科就诊管理系统利用当下成熟完善的SSM框架,使用跨平台的可开发大型商业网站的Java语言,以及最受欢迎的RDBMS应用软件之一的Mysql数据库进行程序开发。实现了用户在线查看数据。管理员管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等功能。牙科就诊管理系统的开发根据操作人员需要设计的界面简洁美观,在功能模块布局上跟同类型网站保持一致,程序在实现基本要求功能时,也为数据信息面临的安全问题提供了一些实用的解决方案。可以说该程序在帮助管理者高效率地处理工作事务的同时,也实现了数据信息的整体化,规范化与自动化。 管理员在后台主要管理病例管理、字典管理、公告管理、药单管理、药品管理、药品收藏管理、药品评价管理、药品订单管理、牙医管理、牙医收藏管理、牙医评价管理、牙医挂号管理、用户管理、管理员管理等。 牙医列表页面,此页面提供给管理员的功能有:查看牙医、新增牙医、修改牙医、删除牙医等。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。药品管理页面,此页面提供给管理员的功能有:新增药品,修改药品,删除药品。药品类型管理页面,此页面提供给管理员的功能有:新增药品类型,修改药品类型,删除药品类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值