Django中的Model操作表的实现

Model 操作表

一、基本操作

# 增

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

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

  dic = {'c1':'xx','c2':'oo'}
  models.Tb1.objects.create(**dic)   #Form的产出结果是一个字典,可以根据这个Form的字典和**直接在数据库创建数据
# 查

models.Tb1.objects.get(id=123)     # 获取单条数据,不存在则报错(不建议)
models.Tb1.objects.all()        # 获取全部   .first() 取第一条数据
models.Tb1.objects.filter(name='seven') # 获取指定条件的数据  也可以用**的方式传参数

# 删

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

# 改

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

obj = models.Tb1.objects.get(id=1)
obj.c1 = '111'
obj.save()                         # 修改单条数据

细看从数据库取出的数据类型 :

w = models.Simp.objects.all()
 print w, type(w)
[<Simp: chenc>, <Simp: zan>, <Simp: zhangsan>]  <class 'django.db.models.query.QuerySet'>

可以看到,从数据库取出个数据看起来像包含对象的列表。而实际上整个数据为django中的特殊类型QuerySet。

.all()是取得所有列的数据,可以加.values()取出某一列,每一项的值为一个字典:

w = models.Simp.objects.all().values('username')
print w, type(w)

[{'username': u'chenc'}, {'username': u'zan'}, {'username': u'zhangsan'}] <class 'django.db.models.query.QuerySet'>

.values_list(),获取到的值为一个元组

w = models.Simp.objects.all().values_list('username')
print w, type(w)

[(u'chenc',), (u'zan',), (u'zhangsan',)] <class 'django.db.models.query.QuerySet'>

.values_list()也可以添加多个参数:(可以配合Form在前端生成动态的select)

w = models.Simp.objects.all().values_list('id', 'username')
print w, type(w)

[(1, u'chenc'), (2, u'zan'), (3, u'zhangsan')] <class 'django.db.models.query.QuerySet'>

query可以查看执行的sql语句:

b = models.Simp.objects.all()
print b.query

SELECT "app01_simp"."id", "app01_simp"."username", "app01_simp"."password" FROM "app01_simp"

二、进阶操作

利用双下划线将字段和对应的操作连接起来

# 获取个数
  #
  # models.Tb1.objects.filter(name='seven').count()

  # 大于,小于
  #
  # 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
  #
  # models.Tb1.objects.filter(name__contains="ven")
  # models.Tb1.objects.filter(name__icontains="ven") # icontains大小写不敏感
  # models.Tb1.objects.exclude(name__icontains="ven")

  # range
  #
  # 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 import Count, Min, Max, Sum
  # models.Tb1.objects.filter(c1=1).values('id').annotate(c=Count('num'))
  # SELECT "app01_tb1"."id", COUNT("app01_tb1"."num") AS "c" FROM "app01_tb1" WHERE "app01_tb1"."c1" = 1 GROUP BY "app01_tb1"."id"

三、操作表之一对多实例

我们来创建一个完整的过程 特别声明:(过程繁琐无聊,纯属作者梳理思路,可以直接跳过看解析)

首先我们先来创造两张表,并设置外键。

class GroupNew(models.Model):

  groupname = models.CharField(max_length=15)

class UserNew(models.Model):

  user = models.CharField(max_length=15)
  10   group = models.ForeignKey(GroupNew)

然后再组表里创建几条数据,配置好url生成数据:

# coding:utf-8

from django.shortcuts import HttpResponse,render
from app01 import models

def Foreign(request):

  models.GroupNew.objects.create(groupname='CEO')
  models.GroupNew.objects.create(groupname='CTO')
  models.GroupNew.objects.create(groupname='COO')
  return HttpResponse('OK')

创建用于生成表单的form:(动态的select)

# coding:utf-8
from django import forms
from app01 import models

class CreateForm(forms.Form):

  user = forms.CharField(max_length=20)

  group = forms.IntegerField(widget=forms.Select())

  def __init__(self, *args, **kwargs):
    super(CreateForm, self).__init__(*args, **kwargs)

    self.fields['group'].widget.choices = models.GroupNew.objects.all().values_list('id', 'groupname')

在views.py里写好创建用户的方法,并应用form:

from app01.forms import foreign as UserForm

def createuser(request):

  obj = UserForm.CreateForm()

  return render(request, 'foreign/createuser.html', {'obj': obj})

创建一个html页面,用来在前端操作创建用户:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>

  <form action="/createuser/" method="post">

    <p>{{ obj.user }}</p>
    <p>{{ obj.group }}</p>

  <input type="submit" value="提交" />

</form>

</body>
</html>

配置好url访问成功:

现在我们要来创建用户数据:(两种方法)

def createuser(request):

  obj = UserForm.CreateForm(request.POST)

  if request.method == 'POST':
    if obj.is_valid():
      all_data = obj.clean()

      group_id = all_data['group']
      username = all_data['user']

      # 1、先获取字典表里的数据对象
      # group_obj = models.GroupNew.objects.get(id=group_id)
      # # 创建用户数据
      # models.UserNew.objects.create(user=username, group=group_obj)

      # 2、 直接传group_id不需获取对象
      models.UserNew.objects.create(user=username, group_id=group_id)

    else:
      pass
  return render(request, 'foreign/createuser.html', {'obj': obj})

还有一种方法是根据Form的修改来创建:(注意:前端页面也需要加上_id与之匹配{{ obj.group_id }} )

forms.py

# coding:utf-8
from django import forms
from app01 import models

class CreateForm(forms.Form):

  user = forms.CharField(max_length=20)

  group_id = forms.IntegerField(widget=forms.Select()) #根据数据库存的字段来修改这里的form使之与数据库相同

  def __init__(self, *args, **kwargs):
    super(CreateForm, self).__init__(*args, **kwargs)

    self.fields['group_id'].widget.choices = models.GroupNew.objects.all().values_list('id', 'groupname')

然后再vires.py里面就可以直接拿到前端传来的字典,直接创建数据了。注意用**的方式传参

from app01.forms import foreign as UserForm

def createuser(request):

  obj = UserForm.CreateForm(request.POST)

  if request.method == 'POST':
    if obj.is_valid():
      all_data = obj.clean()
      print all_data
      # group_id = all_data['group']
      username = all_data['user']

      # 1、先获取字典表里的数据对象
      # group_obj = models.GroupNew.objects.get(id=group_id)
      # # 创建用户数据
      # models.UserNew.objects.create(user=username, group=group_obj)

      # 2、 直接传group_id不需获取对象

      models.UserNew.objects.create(**all_data)  #用**的方式传递字典参数

    else:
      pass
  return render(request, 'foreign/createuser.html', {'obj': obj})

下面我们可以来展示一下数据:

在views.pu里把数据全部拿到,返回到前端:

from app01.forms import foreign as UserForm

def createuser(request):

  obj = UserForm.CreateForm(request.POST)

  if request.method == 'POST':
    if obj.is_valid():
      all_data = obj.clean()
      models.UserNew.objects.create(**all_data)
    else:
      pass

  user_list = models.UserNew.objects.all()  #获取到表中的全部数据

  return render(request, 'foreign/createuser.html', {'obj': obj, 'user_list': user_list})

四、前端和后台获取数据 (了不起的双下划线“__”)

前端页面获取数据展示:

在前端页面不能显示用户组的id,而是直接显示用户组的名称

因为外键对应的字段是一个对象,这个对象代指的是字典表中的一行数据,所以我们在前端取到字典表中的数据用“.”获取

<table>
    {% for item in user_list %}
      <tr>
        <td>{{ item.user }}</td>
        <td>{{ item.group.groupname }}</td>  从对象中获取数据用"."
      </tr>
    {% endfor %}
  </table>

后台获取数据:(了不起的双下划线)

我们在前端用get的方法获取数据,

在浏览器的url后追加字符 http://127.0.0.1:8000/createuser/?group=CEO

例如:我们要展示CEO组里面所以得用户,在views里要如何写呢?

from app01.forms import foreign as UserForm

def createuser(request):

  obj = UserForm.CreateForm(request.POST)

  if request.method == 'POST':
    if obj.is_valid():
      all_data = obj.clean()
      models.UserNew.objects.create(**all_data)
    else:
      pass
  val = request.GET.get('group')
  user_list = models.UserNew.objects.filter(group__groupname=val)  # 去字典表里的数据时用双下划线

  return render(request, 'foreign/createuser.html', {'obj': obj, 'user_list': user_list})

五、解析与总结

所有的联表操作只需理解一点:
model中一般字段为字符串,而外键代表的是一个对象,这个对象就是字典表中的一行数据。

创建数据:

1、根据对象级别来操作表。
表中有外键的字段代指的就是另外一张表的一行数据。在Models里的表现形式就是一个对象,那么我们创建这张表时,给外键的字段传值时也应该传一个对象,而从前台获取到的是一个数字“1”,1不是一个对象,根据这个“1”先创建一个字典表的对象,所以根据前台的“1”先获取字典表里对应的数据对象,把这个对象传递到创建表时所需的对象参数即可。
(其实也是把对象转换成sql语句拼接成带_id的样式,有一种多此一举的感觉)

2、根据数据库级别来操作表。
首先我们可以先查看一下数据库表中的外键值的样式 user_group_id。“_id”在models没有定义的,是django自动为我们定义的样式。所以我们在向数据库中插入数据的时候,外键的字段应该加上_id,这样就可以直接传从前台获取的数字了。
(可以再form中修改外键的值,加"_id",这样传到后台的数据就能直接拿到一个字典,在用**的方式传值创建数据)

获取数据:

跨表取数据用 "."
因为在models里的外键代指的是另外一张表的一行数据,且这个数据类型为一个对象。
那么就可以根据这个对象直接找到那行数据里对应的字段。用 “.”获取
在前端页面就可以{{item.group.groupname}}方式获取到。

跨表过滤数据时用 “__”
过滤数据用双下划线 “__”(group__groupname=val),如果有多张表建立外键继续用双下划线“__”跨表查询数据

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 解决django model修改添加字段报错的问题

    关于django models中添加字段的一个小节,记录下 django的models中已经写好了字段,可是后面我又想在添加一些字段,于是就在models中添加了字段 ,发现报错了 报错的类型: 字段重复了 不知道的列 : 最后解决的方法 : 到models的目录下打开文件 ,直接把所需的字段添加到第一次编译的文件中 , 重新执行数据库的迁移 ,如果依然有报错,提示有未知的列 ,就查看数据库 ,那个列缺失,就把列给添加上 添加未知的列 至此,重新执行迁移 ,妥妥的成功了 ! 以上这篇解决djan

  • 利用Django提供的ModelForm增删改数据的方法

    上一篇我们写了Django基于类如何增删改数据的方法,方法虽然简单,但新手可能对其原理不是很清楚,那么我们这次就用Django提供的ModelForm方法来实现增删改数据,这是一种基于现有模型的增删改方法. 一个简单的例子加以说明,前提是你已经具备Django创建项目应用的基本知识: 01.首先创建一个简单的模型,模型只有三个文本字段,标题 title , 内容 text , 添加日期 date_added ,如下: # models.py from django.db import model

  • Django的models模型的具体使用

    model的常用字段 V=models.CharField(max_length=None[, **options]) #varchar V=models.EmailField([max_length=75, **options]) #varchar V=models.URLField([verify_exists=True, max_length=200, **options]) #varchar V=models.FileField(upload_to=None[, max_length=1

  • Django admin.py 在修改/添加表单界面显示额外字段的方法

    问题描述: 我有个blogextra表继承自blog,现在我想在blog的admin管理change界面显示对应的blogextra字段 解决方法: 可以使用admin.py的inline内联方法 代码: models.py from django.db import models # Create your models here. class Blog(models.Model): Name = models.CharField(max_length=350) def __unicode__

  • Django中的Model操作表的实现

    Model 操作表 一.基本操作 # 增 models.Tb1.objects.create(c1='xx', c2='oo') #增加一条数据,可以接受字典类型数据 **kwargs obj = models.Tb1(c1='xx', c2='oo') obj.save() dic = {'c1':'xx','c2':'oo'} models.Tb1.objects.create(**dic) #Form的产出结果是一个字典,可以根据这个Form的字典和**直接在数据库创建数据 # 查 mod

  • Django中模型Model添加JSON类型字段的方法

    本文实例讲述了Django中模型Model添加JSON类型字段的方法.分享给大家供大家参考.具体如下: Django里面让Model用于JSON字段,添加一个JSONField自动类型如下: class JSONField(models.TextField): __metaclass__ = models.SubfieldBase description = "Json" def to_python(self, value): v = models.TextField.to_pytho

  • Django中Model的使用方法教程

    前言 本文主要给大家介绍了关于Django中Model使用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 创建模型 使用Django的模型主要注意两个方面:字段的类型和方法的重写.这里用一个例子来说明,其中包含了常用的字段类型和如何重写方法. from django.db import models class School(models.Model): pass class Message(models.Model): pass class Teacher(mod

  • 浅谈Django中的数据库模型类-models.py(一对一的关系)

    如下所示: # -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import models # Create your models here. # 一对一关系:数据库中两个表中数据的对应关系 # 一个账户对应着一个联系人,而一个联系人有一个账户 # 一对一关系是通过在两个表之间定义相同的主键来完成 class Account(models.Model): username = models

  • Django基础之Model操作步骤(介绍)

    一.数据库操作 1.创建model表 基本结构: #coding:Utf8 from django.db import models class userinfo(models.Model): #如果没有models.AutoField,默认会创建一个id的自增列 name = models.CharField(max_length=30) email = models.EmailField() memo = models.TextField() 字段解释: 1.models.AutoField

  • Django中使用group_by的方法

    本文实例讲述了Django中使用group_by的方法.分享给大家供大家参考.具体分析如下: 在Django中怎样使用group_by语句呢?找了很多资料,都没有看到好的,在这里分享两种方法给大家: 首先,我们先建一个简单的模型. class Book(models.Model): name = models.CharField(u'书名',max_length=255,db_index = True) author = models.CharField(u'作者',max_length=255

  • Django中实现一个高性能计数器(Counter)实例

    计数器(Counter)是一个非常常用的功能组件,这篇blog以未读消息数为例,介绍了在 Django中实现一个高性能计数器的基本要点. 故事的开始:.count() 假设你有一个Notification Model类,保存的主要是所有的站内通知: 复制代码 代码如下: class Notification(models.Model):     """一个简化过的Notification类,拥有三个字段: - `user_id`: 消息所有人的用户ID     - `has_

  • django中的setting最佳配置小结

    Django settings详解 1.基础 DJANGO_SETTING_MODULE环境变量:让settings模块被包含到python可以找到的目录下,开发情况下不需要,我们通常会在当前文件夹运行,python可以搜索到.如果需要运行在其他服务器上,就必须指定DJANGO_SETTINGS_MODULE变量. 2.默认设定 一个django的settings文件不需要我们手动去设置所有项目,因为系统已经默认设置好了.我们只需要修改我们使用的设 定就好了.默认的设置在django/conf/

  • Django中ORM表的创建和增删改查方法示例

    前言 Django作为重量级的Python web框架,在做项目时肯定少不了与数据库打交道,编程人员对数据库的语法简单的还行,但过多的数据库语句不是编程人员的重点对象.因此用ORM来操作数据库相当快捷.今天来介绍一下用ORM操作数据库. 一.创建Django项目 可以使用pycharme专业版直接快速创建.如果不是专业版也可以使用命令进行创建.下面列出命令行创建方式: django-admin startproject orm_test 这时会在当前目录创建文件夹名为orm_test,接下来进入

  • Django中的Signal代码详解

    本文研究的主要是Django开发中的signal 的相关内容,具体如下. 前言 在web开发中, 你可能会遇到下面这种场景: 在用户完成某个操作后, 自动去执行一些后续的操作. 譬如用户完成修改密码后, 你要发送一份确认邮件. 当然可以把逻辑写在一起,但是有个问题是,触发操作一般不止一种(如用户更改了其它信息的确认邮件),这时候这个逻辑会需要写多次,所以你可能会想着DRY(Don't repeat yourself),于是你把它写到了一个函数中,每次调用.当然这是没问题的. 但是, 如果你换个思

随机推荐