Django models笔记

models例子如下,本文主要针对该例子来描述
from django.db import models

# Create your models here.
class Publisher(models.Model):
 name = models.CharField(max_length = 30)
 address = models.CharField(max_length=50)
 city = models.CharField(max_length=60)
 state_province=models.CharField(max_length=30)
 country = models.CharField(max_length=50)
 website = models.URLField()
 
 def __unicode__(self):
  return "name:%s, address:%s" % (self.name, self.address)
 
class Author(models.Model):
 first_name = models.CharField(max_length = 30)
 last_name = models.CharField(max_length=40)
 email = models.EmailField(blank=True)
 
 def __unicode__(self):
  return self.last_name
 
class Book(models.Model):
 tille = models.CharField(max_length=100)
 authors = models.ManyToManyField(Author)
 publisher = models.ForeignKey(Publisher)
 publication_date = models.DateField()
 
 def __unicode__(self):
  return self.tille

 

     1.基本操作
from website.app import models

1)insert
p1 = models.Publisher(name='Apress', address='2855 Telegraph Avenue',
     city='Berkeley', state_province='CA', country='U.S.A.',
     website='http://www.apress.com/')
p1.save()

2)select
publisher_list = models.Publisher.objects.all()
publisher_No.1 = models.Publisher.objects.all()[0:2]

3)update
p = models.Publisher.objects.all()[0]#取出第一条记录的指针
p.name="hongxing"#将名字改为hongxing
p.save()#保存

4)filter
models.Publisher.objects.filter(name='hongxing')#单条件搜索
models.Publisher.objects.filter(name="chubanshe",city='beijing')#and条件
mdoels.Publisher.objects.filter(name='hognxing').update(city='zaozhuang')

5)like
models.Publisher.objects.filter(name__contains='hong')#所有名字中包含hong的记录

6)retrieving single objects
models.Publisher.objects.get(name="hongxing")

7)order
models.Publisher.objects.order_by('name')
models.Publisher.objects.order_by('name', 'city')
models.Publisher.objects.order_by('-name')#倒序

指定默认的排序方式:
class Publisher(models.Model):
    name = models.CharField(max_length=30)
    address = models.CharField(max_length=50)
    city = models.CharField(max_length=60)
    state_province = models.CharField(max_length=30)
    country = models.CharField(max_length=50)
    website = models.URLField()

    def __unicode__(self):
        return self.name
    
    class Meta:
     ordering=['name']
    
8)Chaining Lookups
mdoels.Publisher.objects.filter('name').order_by('city')

9)delete
models.Publisher.objects.get(name='hognxing').delete()

 

2.Foreign Key

1)ForeignKey用来定义多对一得关系,ForeignKey的参数是主键的类,就像文章开始
用的例子,Book.publisher的ForeignKey参数就是Publisher类。

2)对象也可以和自身关联,用mdels.ForeignKey('self'),这样就建立了一种递归关系。

3)在2)中用到了字符串,是的,外键参数可以用字符串的,这个在参数类还没有定义的时候
尤其适用,比如在Publisher类没有定义时,你完全可以用models.ForeignKey('Publisher')
注意:只能对同一个models.py文件中的模型适用字符串引用,其他的或者导入的模型不可用。

4)访问
在文章开始给出的models可以看出,Book中有外键publisher
如下代码所示,通过book的object访问publisher同访问正常field没区别。
但是通过主键Publisher访问book时,需要用book_set的形式。
即:主键中模型类名的小写+_set

>>> from website.books import models
>>> b = models.Book.objects.get(tille='djangobook')
>>> p=models.Publisher.objects.filter(name='Apress')[0]
>>> b.publisher
<Publisher: name:Apress, address:2855 Telegraph Avenue>
>>> p.book_set.all()
[<Book: djangobook>, <Book: pythonbook>]
 
    3.ManyToMany
1)ManyToManyField放在哪个模型中
分析文章开始给出的例子:一个作者可以写多本书,一本书可以有多本书
这个Field放在Book中还是Author中都可以。但是不能两个都放。

2)关于自关联以及字符串参数等同ForeignKey一样。

3)访问同ForeignKey类似
这里说明一点。book_set属性一定是author的一条记录而不能是QuerySet

正向访问:
>>> book = models.Book.objects.get(tille='djangobook')
>>> book.authors.all()
[<Author: yonggao>, <Author: xiuqi>]
反向访问:
>>> aut = models.Author.objects.filter(last_name__contains='yonggao')
>>> aut.book_set.all()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'QuerySet' object has no attribute 'book_set'
>>>
>>> aut = aut[0]
>>> aut.book_set.all()
[<Book: djangobook>, <Book: pythonbook>]
 
   4.修改数据库模型
创建好数据库后,如果在添加和删除列,python manage.py syncdb就不起作用了。
本节主要学些关于修改数据库列的知识。
1)django对models和database同步处理,这里直接引用原文更好些:
■Django will complain loudly if a model contains a field that has not yet been created in the 
database table. This will cause an error the first time you use the Django database API to query 
the given table (i.e., it will happen at code execution time, not at compilation time).
■Django does not care if a database table contains columns that are not defined in the model.
■Django does not care if a database contains a table that is not represented by a model.

2)变更字段
在添加字段时,可以现在models.py中添加上要添加的内容
然后通过python manage.py sqlall books来看books app中数据库创建
语句,这样根据sql语句,可以很轻松的使用alter命令来修改自己的数据库。

    5.Managers
Book.objects.all()中objetcs就是一个Manager的例子。那么什么时候需要
定制自己的manager呢: to add extra manager methods, and/or 
to modify the initial QuerySet the manager returns.

1)Adding Extra Manager Methods
例子:
给Book Model添加一个可以统计指定关键字个数的方法

class BookManager(models.Manager):
 def title_count(self,keyword):
  return self.filter(tille__icontains=keyword).count()

class Book(models.Model):
 tille = models.CharField(max_length=100)
 authors = models.ManyToManyField(Author)
 publisher = models.ForeignKey(Publisher)
 publication_date = models.DateField()
 objects = BookManager()
 
 def __unicode__(self):
  return self.tille
  
2)Modifying Initial Manager QuerySets
管理器默认的QuerySet返回表中的所有记录,如果有需要可以定制返回内容。
只需要重写Manager.get_query_set()就可以了。
举例:下面的model如果用dahl管理器则在使用Book.dahl_ojbects.all()时
只会返回所有yonggao写的书。

from django.db import models

# First, define the Manager subclass.
class DahlBookManager(models.Manager):
    def get_query_set(self):
        return super(DahlBookManager, self).get_query_set().filter(author='yonggao')

# Then hook it into the Book model explicitly.
class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.CharField(max_length=50)
    # ...

    objects = models.Manager() # The default manager.
    dahl_objects = DahlBookManager() # The Dahl-specific manager.
    
上面例子的注意点:
当自己定义管理器时,请总要保留models.Manager()这个默认管理器。

自定义管理器可以用来定义共通的过滤器例如下面的例子,使用不同的
Manager来管理不同的数据更容易。

class MaleManager(models.Manager):
    def get_query_set(self):
        return super(MaleManager, self).get_query_set().filter(sex='M')

class FemaleManager(models.Manager):
    def get_query_set(self):
        return super(FemaleManager, self).get_query_set().filter(sex='F')

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
    people = models.Manager()
    men = MaleManager()
    women = FemaleManager()

一个注意点:如果在model中定义了多个manager,则第一个manager是django的默认
管理器。django的很多部分会用默认manager来处理model。

 

     6.Executing Raw SQL Queries
你可以再django使用标准的python数据库语句。

另外,推荐方法是将sql statemets放在model methods活manager methods中。
例子:
from django.db import connection, models

class PersonManager(models.Manager):
    def first_names(self, last_name):
        cursor = connection.cursor()
        cursor.execute("""
            SELECT DISTINCT first_name
            FROM people_person
            WHERE last_name = %s""", [last_name])
        return [row[0] for row in cursor.fetchone()]

class Person(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    objects = PersonManager()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值