zoukankan      html  css  js  c++  java
  • Django模块笔记【一】

    入门笔记翻译整理自:https://docs.djangoproject.com/en/1.8/topics/

    *该笔记将对各个模块进行单独介绍

    *Model&Database

    1. 模型(models)

    模型是数据的唯一信息源,它指示了数据的域(fields)和行为(behaviors)。每个模型都对应一个数据库表。

    ①每个模型都是django.db.models.Model的子类;②模型的每个属性代表了数据库的域;③数据库入口API,参考making queries部分。

    比如,

    1 from django.db import models
    2 
    3 class Person(models.Model):
    4     first_name = models.CharField(max_length=30)
    5     last_name = models.CharField(max_length=30)

    对应的数据库表:

    1 CREATE TABLE myapp_person (
    2     "id" serial NOT NULL PRIMARY KEY,
    3     "first_name" varchar(30) NOT NULL,
    4     "last_name" varchar(30) NOT NULL
    5 );

    使用模型:

    INSTALLED_APPS = (
        #...
        'myapp',
        #...
    )

    2. 域(Fields)

    Django使用Field类来决定:①数据库的列类型(如INTEGER, VARCHAR);②HTML widget(如<input type="text">,<select>)

    各种Field的属性不尽相同,但是它们也有一些共同的可选属性。null=True,将空值存储为NULL,默认为False;blank=True,允许空值,默认为False;choices,举例如下:

     1 from django.db import models
     2 
     3 class Person(models.Model):
     4     SHIRT_SIZES = (
     5         ('S', 'Small'),
     6         ('M', 'Medium'),
     7         ('L', 'Large'),
     8     )
     9     name = models.CharField(max_length=60)
    10     shirt_size = models.CharField(max_length=1, choices=SHIRT_SIZES)
    1 >>> p = Person(name="Fred Flintstone", shirt_size="L")
    2 >>> p.save()
    3 >>> p.shirt_size
    4 'L'
    5 >>> p.get_shirt_size_display()
    6 'Large'

    default,定义field的默认值;help_text,在表单widget中显示帮助文档;primary_key=True,相应Field为主键,否则会自动生成主键,主键不可更改,比如:

    1 from django.db import models
    2 
    3 class Fruit(models.Model):
    4     name = models.CharField(max_length=100, primary_key=True)
    1 >>> fruit = Fruit.objects.create(name='Apple')
    2 >>> fruit.name = 'Pear'
    3 >>> fruit.save()
    4 >>> Fruit.objects.values_list('name', flat=True)
    5 ['Apple', 'Pear']

    unique=True,相应Field的值必须为独一无二的。

    大多数域可以直接设置域别名(Verbose field names):

    1 # verbose name is "person's first name"
    2 first_name = models.CharField("person's first name", max_length=30)
    3 # verbose name is "first name"
    4 first_name = models.CharField(max_length=30)

    ForeighKey,ManyToManyField和OneToOneField需要使用verbose_name参数,来设置域别名:

    1 poll = models.ForeignKey(Poll, verbose_name="the related poll")
    2 sites = models.ManyToManyField(Site, verbose_name="list of sites")
    3 place = models.OneToOneField(Place, verbose_name="related place")

    数据库中常见的三种关系为:多对一,多对多,一对一。

    ①多对一

    1 from django.db import models
    2 
    3 class Manufacturer(models.Model):
    4     # ...
    5     pass
    6 
    7 class Car(models.Model):
    8     manufacturer = models.ForeignKey(Manufacturer)
    9     # ...

    ②多对多

    1 from django.db import models
    2 
    3 class Topping(models.Model):
    4     # ...
    5     pass
    6 
    7 class Pizza(models.Model):
    8     # ...
    9     toppings = models.ManyToManyField(Topping)

    或者

     1 from django.db import models
     2 
     3 class Person(models.Model):
     4     name = models.CharField(max_length=128)
     5 
     6     def __str__(self):              # __unicode__ on Python 2
     7         return self.name
     8 
     9 class Group(models.Model):
    10     name = models.CharField(max_length=128)
    11     members = models.ManyToManyField(Person, through='Membership')
    12 
    13     def __str__(self):              # __unicode__ on Python 2
    14         return self.name
    15 
    16 class Membership(models.Model):
    17     person = models.ForeignKey(Person)
    18     group = models.ForeignKey(Group)
    19     date_joined = models.DateField()
    20     invite_reason = models.CharField(max_length=64)

    ③一对一

     1 from django.db import models
     2 
     3 class Place(models.Model):
     4     name = models.CharField(max_length=50)
     5     address = models.CharField(max_length=80)
     6 
     7     def __str__(self):              # __unicode__ on Python 2
     8         return "%s the place" % self.name
     9 
    10 class Restaurant(models.Model):
    11     place = models.OneToOneField(Place, primary_key=True)
    12     serves_hot_dogs = models.BooleanField(default=False)
    13     serves_pizza = models.BooleanField(default=False)
    14 
    15     def __str__(self):              # __unicode__ on Python 2
    16         return "%s the restaurant" % self.place.name

    3. 文档间模型(Models across files)

    需要先导入相应模块:

    1 from django.db import models
    2 from geography.models import ZipCode
    3 
    4 class Restaurant(models.Model):
    5     # ...
    6     zip_code = models.ForeignKey(ZipCode)

    4. 元选项(Meta options)

    meta用于接收一切不是Field的数据。

    1 from django.db import models
    2 
    3 class Ox(models.Model):
    4     horn_length = models.IntegerField()
    5 
    6     class Meta:
    7         ordering = ["horn_length"]
    8         verbose_name_plural = "oxen"

    5. 重写方法(Override predefined model methods)

     1 from django.db import models
     2 
     3 class Blog(models.Model):
     4     name = models.CharField(max_length=100)
     5     tagline = models.TextField()
     6 
     7     def save(self, *args, **kwargs):
     8         do_something()
     9         super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.
    10         do_something_else()

    重写为

     1 from django.db import models
     2 
     3 class Blog(models.Model):
     4     name = models.CharField(max_length=100)
     5     tagline = models.TextField()
     6 
     7     def save(self, *args, **kwargs):
     8         if self.name == "Yoko Ono's blog":
     9             return # Yoko shall never have her own blog!
    10         else:
    11             super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.

    6. 模型继承(Model inheritance)

    ①抽象基类(Abstract base classes)

     1 from django.db import models
     2 
     3 class CommonInfo(models.Model):
     4     name = models.CharField(max_length=100)
     5     age = models.PositiveIntegerField()
     6 
     7     class Meta:
     8         abstract = True
     9 
    10 class Student(CommonInfo):
    11     home_group = models.CharField(max_length=5)

     元继承

     1 from django.db import models
     2 
     3 class CommonInfo(models.Model):
     4     # ...
     5     class Meta:
     6         abstract = True
     7         ordering = ['name']
     8 
     9 class Student(CommonInfo):
    10     # ...
    11     class Meta(CommonInfo.Meta):
    12         db_table = 'student_info'

    ②多表继承

    父类和子类使用不同的数据库表。

    1 from django.db import models
    2 
    3 class Place(models.Model):
    4     name = models.CharField(max_length=50)
    5     address = models.CharField(max_length=80)
    6 
    7 class Restaurant(Place):
    8     serves_hot_dogs = models.BooleanField(default=False)
    9     serves_pizza = models.BooleanField(default=False)
    1 >>> p = Place.objects.get(id=12)
    2 # If p is a Restaurant object, this will give the child class:
    3 >>> p.restaurant
    4 <Restaurant: ...>

    元继承

    1 class ChildModel(ParentModel):
    2     # ...
    3     class Meta:
    4         # Remove parent's ordering effect
    5         ordering = []

    ③代理模型(Proxy model)

    父类和子类使用相同的数据库表。

     1 from django.db import models
     2 
     3 class Person(models.Model):
     4     first_name = models.CharField(max_length=30)
     5     last_name = models.CharField(max_length=30)
     6 
     7 class MyPerson(Person):
     8     class Meta:
     9         proxy = True
    10 
    11     def do_something(self):
    12         # ...
    13         pass
    1 >>> p = Person.objects.create(first_name="foobar")
    2 >>> MyPerson.objects.get(first_name="foobar")
    3 <MyPerson: foobar>
    1 class OrderedPerson(Person):
    2     class Meta:
    3         ordering = ["last_name"]
    4         proxy = True

    7. 多重继承

    1 class Article(models.Model):
    2     headline = models.CharField(max_length=50)
    3     body = models.TextField()
    4 
    5 class Book(models.Model):
    6     title = models.CharField(max_length=50)
    7 
    8 class BookReview(Book, Article):
    9     pass

    ————————————————————————————————————————————————————————————————————————————————————————————

    8. 创建队列(Making queries)

    以下模型创建了一个网页博客应用,将以此为例:

     1 from django.db import models
     2 
     3 class Blog(models.Model):
     4     name = models.CharField(max_length=100)
     5     tagline = models.TextField()
     6 
     7     def __str__(self):              # __unicode__ on Python 2
     8         return self.name
     9 
    10 class Author(models.Model):
    11     name = models.CharField(max_length=50)
    12     email = models.EmailField()
    13 
    14     def __str__(self):              # __unicode__ on Python 2
    15         return self.name
    16 
    17 class Entry(models.Model):
    18     blog = models.ForeignKey(Blog)
    19     headline = models.CharField(max_length=255)
    20     body_text = models.TextField()
    21     pub_date = models.DateField()
    22     mod_date = models.DateField()
    23     authors = models.ManyToManyField(Author)
    24     n_comments = models.IntegerField()
    25     n_pingbacks = models.IntegerField()
    26     rating = models.IntegerField()
    27 
    28     def __str__(self):              # __unicode__ on Python 2
    29         return self.headline

    创建和更改对象

    1 >>> from blog.models import Blog
    2 >>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
    3 >>> b.save()
    4 >>> b5.name = 'New name'
    5 >>> b5.save()

    储存外键和多对多域

    1 >>> from blog.models import Entry
    2 >>> entry = Entry.objects.get(pk=1)
    3 >>> cheese_blog = Blog.objects.get(name="Cheddar Talk")
    4 >>> entry.blog = cheese_blog
    5 >>> entry.save()
    1 >>> john = Author.objects.create(name="John")
    2 >>> paul = Author.objects.create(name="Paul")
    3 >>> george = Author.objects.create(name="George")
    4 >>> ringo = Author.objects.create(name="Ringo")
    5 >>> entry.authors.add(john, paul, george, ringo)

    检索对象(Retrieve objects)

    1 >>> Blog.objects
    2 <django.db.models.manager.Manager object at ...>
    3 >>> b = Blog(name='Foo', tagline='Bar')
    4 >>> b.objects
    5 Traceback:
    6     ...
    7 AttributeError: "Manager isn't accessible via Blog instances."
    1 >>> all_entries = Entry.objects.all()
    1 Entry.objects.filter(pub_date__year=2006)
    1 >>> Entry.objects.filter(
    2 ...     headline__startswith='What'
    3 ... ).exclude(
    4 ...     pub_date__gte=datetime.date.today()
    5 ... ).filter(
    6 ...     pub_date__gte=datetime(2005, 1, 30)
    7 ... )
    1 one_entry = Entry.objects.get(pk=1)
    1 >>> Entry.objects.all()[:5]
    2 >>> Entry.objects.all()[:10:2]
    1 Entry.objects.order_by('headline')[0]

    查询域(Field lookup)

    类似于检索对象,主要以双下划线的形式实现。

    1 >>> Entry.objects.filter(pub_date__lte='2006-01-01')
    2 >>> Entry.objects.get(headline__exact="Man bites dog")
    3 >>> Blog.objects.get(name__iexact="beatles blog")
    4 >>> Entry.objects.get(headline__contains='Lennon')

    此外,还有icontains, startswith, endswith, istartswith, iendswith等。

    可以多次使用双下划线,来扩展关系,比如:

    1 Blog.objects.filter(entry__headline__contains='Lennon')

    可以使用F表达式来进行不同域之间的比较:

    1 >>> from django.db.models import F
    2 >>> Entry.objects.filter(n_comments__gt=F('n_pingbacks'))
    3 >>> Entry.objects.filter(rating__lt=F('n_comments') + F('n_pingbacks'))
    4 >>> Entry.objects.filter(authors__name=F('blog__name'))

    编码时注意缓冲区(Cache)可以减少内存消耗,此处略过。

    可以使用Q表达式进行复杂的查询功能,配合使用&,|,~三个运算符:

    1 from django.db.models import Q
    2 Q(question__startswith='What')
    3 Q(question__startswith='Who') | ~Q(pub_date__year=2005)

    比较和删除对象:

    1 >>> some_entry == other_entry
    2 >>> some_entry.id == other_entry.id
    3 >>> e.delete()
    4 >>> Entry.objects.filter(pub_date__year=2005).delete()

    拷贝模型:

    1 blog = Blog(name='My blog', tagline='Blogging is easy')
    2 blog.save() # blog.pk == 1
    3 
    4 blog.pk = None
    5 blog.save() # blog.pk == 2

    更复杂一点的拷贝模型:

    1 class ThemeBlog(Blog):
    2     theme = models.CharField(max_length=200)
    3 
    4 django_blog = ThemeBlog(name='Django', tagline='Django is easy', theme='python')
    5 django_blog.save() # django_blog.pk == 3
    6 
    7 django_blog.pk = None
    8 django_blog.id = None
    9 django_blog.save() # django_blog.pk == 4

    更新对象:

    1 Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')

    关系对象:

    1 >>> e = Entry.objects.get(id=2)
    2 >>> e.blog # Returns the related Blog object.

    ———————————————————————————————————————————————————————————————————————————————————————————

    9. 整合(Aggregation)

    整合和队列功能类似,适合在求平均,总和时使用。

     1 from django.db import models
     2 
     3 class Author(models.Model):
     4     name = models.CharField(max_length=100)
     5     age = models.IntegerField()
     6 
     7 class Publisher(models.Model):
     8     name = models.CharField(max_length=300)
     9     num_awards = models.IntegerField()
    10 
    11 class Book(models.Model):
    12     name = models.CharField(max_length=300)
    13     pages = models.IntegerField()
    14     price = models.DecimalField(max_digits=10, decimal_places=2)
    15     rating = models.FloatField()
    16     authors = models.ManyToManyField(Author)
    17     publisher = models.ForeignKey(Publisher)
    18     pubdate = models.DateField()
    19 
    20 class Store(models.Model):
    21     name = models.CharField(max_length=300)
    22     books = models.ManyToManyField(Book)
    23     registered_users = models.PositiveIntegerField()

    以上面这个模型为例:

     1 # Total number of books.
     2 >>> Book.objects.count()
     3 # Total number of books with publisher=BaloneyPress
     4 >>> Book.objects.filter(publisher__name='BaloneyPress').count()
     5 
     6 # Average price across all books.
     7 >>> from django.db.models import Avg
     8 >>> Book.objects.all().aggregate(Avg('price'))
     9 {'price__avg': 34.35}
    10 
    11 # Max price across all books.
    12 >>> from django.db.models import Max
    13 >>> Book.objects.all().aggregate(Max('price'))
    14 {'price__max': Decimal('81.20')}
    15 
    16 # Cost per page
    17 >>> Book.objects.all().aggregate(
    18 ...    price_per_page=Sum(F('price')/F('pages'), output_field=FloatField()))
    19 {'price_per_page': 0.4470664529184653}
    20 
    21 # All the following queries involve traversing the Book<->Publisher
    22 # many-to-many relationship backward
    23 
    24 # Each publisher, each with a count of books as a "num_books" attribute.
    25 >>> from django.db.models import Count
    26 >>> pubs = Publisher.objects.annotate(num_books=Count('book'))
    27 >>> pubs
    28 [<Publisher BaloneyPress>, <Publisher SalamiPress>, ...]
    29 >>> pubs[0].num_books
    30 
    31 # The top 5 publishers, in order by number of books.
    32 >>> pubs = Publisher.objects.annotate(num_books=Count('book')).order_by('-num_books')[:5]
    33 >>> pubs[0].num_books

    ———————————————————————————————————————————————————————————————————————————————————————————

    10. 管理器(Managers)

    每个Django应用中都有管理器,创建队列一节中已经解释了管理器的工作原理,这节介绍自定义管理器行为。

    管理器可以重设名称:

    1 # Person.people.all() will provide a list of all Person objects.
    2 
    3 from django.db import models
    4 
    5 class Person(models.Model):
    6     #...
    7     people = models.Manager()

    额外添加管理器方法:

     1 from django.db import models
     2 
     3 class PollManager(models.Manager):
     4     def with_counts(self):
     5         from django.db import connection
     6         cursor = connection.cursor()
     7         cursor.execute("""
     8             SELECT p.id, p.question, p.poll_date, COUNT(*)
     9             FROM polls_opinionpoll p, polls_response r
    10             WHERE p.id = r.poll_id
    11             GROUP BY p.id, p.question, p.poll_date
    12             ORDER BY p.poll_date DESC""")
    13         result_list = []
    14         for row in cursor.fetchall():
    15             p = self.model(id=row[0], question=row[1], poll_date=row[2])
    16             p.num_responses = row[3]
    17             result_list.append(p)
    18         return result_list
    19 
    20 class OpinionPoll(models.Model):
    21     question = models.CharField(max_length=200)
    22     poll_date = models.DateField()
    23     objects = PollManager()
    24 
    25 class Response(models.Model):
    26     poll = models.ForeignKey(OpinionPoll)
    27     person_name = models.CharField(max_length=50)
    28     response = models.TextField()

     修改初始管理器查询集:

     1 # First, define the Manager subclass.
     2 class DahlBookManager(models.Manager):
     3     def get_queryset(self):
     4         return super(DahlBookManager, self).get_queryset().filter(author='Roald Dahl')
     5 
     6 # Then hook it into the Book model explicitly.
     7 class Book(models.Model):
     8     title = models.CharField(max_length=100)
     9     author = models.CharField(max_length=50)
    10 
    11     objects = models.Manager() # The default manager.
    12     dahl_objects = DahlBookManager() # The Dahl-specific manager.

    也可以在模型中多次调用管理器,这里略过。

    此外,可以自定义查询集方法,并在管理器调用:

     1 class PersonQuerySet(models.QuerySet):
     2     def authors(self):
     3         return self.filter(role='A')
     4 
     5     def editors(self):
     6         return self.filter(role='E')
     7 
     8 class PersonManager(models.Manager):
     9     def get_queryset(self):
    10         return PersonQuerySet(self.model, using=self._db)
    11 
    12     def authors(self):
    13         return self.get_queryset().authors()
    14 
    15     def editors(self):
    16         return self.get_queryset().editors()
    17 
    18 class Person(models.Model):
    19     first_name = models.CharField(max_length=50)
    20     last_name = models.CharField(max_length=50)
    21     role = models.CharField(max_length=1, choices=(('A', _('Author')), ('E', _('Editor'))))
    22     people = PersonManager()

    如果想同时自定义查询集和管理器,可以使用from_queryset()方法:

     1 class BaseManager(models.Manager):
     2     def manager_only_method(self):
     3         return
     4 
     5 class CustomQuerySet(models.QuerySet):
     6     def manager_and_queryset_method(self):
     7         return
     8 
     9 class MyModel(models.Model):
    10     objects = BaseManager.from_queryset(CustomQueryset)()

    管理器可以随类继承,多重继承时需小心,此处略过。

    可以通过use_for_related_fields方法设置自定义管理器为默认管理器:

    1 class MyManager(models.Manager):
    2     use_for_related_fields = True
    3     # ...

    ———————————————————————————————————————————————————————————————————————————————————————————

    11. 使用原始SQL队列(Performing raw SQL queries)

    在Django提供的语句不足以实现复杂的SQL时,可以使用Manager.raw()来编写原始队列。比如对于以下模型:

    1 class Person(models.Model):
    2     first_name = models.CharField(...)
    3     last_name = models.CharField(...)
    4     birth_date = models.DateField(...)

    可以以如下方式执行:

    1 >>> for p in Person.objects.raw('SELECT * FROM myapp_person'):
    2 ...     print(p)
    3 John Smith
    4 Jane Jones

    也可以运用Connection实现原始SQL查询:

     1 from django.db import connection
     2 
     3 def my_custom_sql(self):
     4     cursor = connection.cursor()
     5 
     6     cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
     7 
     8     cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
     9     row = cursor.fetchone()
    10 
    11     return row

    关于Connection和Cursor的具体用法,可以参见Python DB-API的内容。

    ———————————————————————————————————————————————————————————————————————————————————————————

    12. 数据库事务(Database transactions)

    处理网页事务的方法是将每个请求放入一个事务中,同时在数据库的配置(Configuration)中设置ATOMIC_REQUESTS为True。

    当ATOMIC_REQUESTS激活时,可以使用non_atomic_requests来阻止某视图在事务中运行。比如:

    1 from django.db import transaction
    2 
    3 @transaction.non_atomic_requests
    4 def my_view(request):
    5     do_stuff()
    6 
    7 @transaction.non_atomic_requests(using='other')
    8 def my_other_view(request):
    9     do_stuff_on_the_other_database()

    可以使用atomic来将代码块设置为事务,如果事务运行成功则操作数据库,否则,会执行回滚。例如:

     1 # as a decorator
     2 
     3 from django.db import transaction
     4 
     5 @transaction.atomic
     6 def viewfunc(request):
     7     # This code executes inside a transaction.
     8     do_stuff()
     9 
    10 # as a context manager
    11 
    12 from django.db import transaction
    13 
    14 def viewfunc(request):
    15     # This code executes in autocommit mode (Django's default).
    16     do_stuff()
    17 
    18     with transaction.atomic():
    19         # This code executes inside a transaction.
    20         do_more_stuff()

    以下代码在部分代码出现错误时,也会执行事务操作:

     1 from django.db import IntegrityError, transaction
     2 
     3 @transaction.atomic
     4 def viewfunc(request):
     5     create_parent()
     6 
     7     try:
     8         with transaction.atomic():
     9             generate_relationships()
    10     except IntegrityError:
    11         handle_exception()
    12 
    13     add_children()

    事务以任意一种方式结束:commit或者rollback。

    事务中savepoint的使用如下:

     1 from django.db import transaction
     2 
     3 # open a transaction
     4 @transaction.atomic
     5 def viewfunc(request):
     6 
     7     a.save()
     8     # transaction now contains a.save()
     9 
    10     sid = transaction.savepoint()
    11 
    12     b.save()
    13     # transaction now contains a.save() and b.save()
    14 
    15     if want_to_keep_b:
    16         transaction.savepoint_commit(sid)
    17         # open transaction still contains a.save() and b.save()
    18     else:
    19         transaction.savepoint_rollback(sid)
    20         # open transaction now contains only a.save()

    ———————————————————————————————————————————————————————————————————————————————————————————

    13. 多个数据库

    在settings.py设置多个数据库:

     1 DATABASES = {
     2     'default': {
     3         'NAME': 'app_data',
     4         'ENGINE': 'django.db.backends.postgresql_psycopg2',
     5         'USER': 'postgres_user',
     6         'PASSWORD': 's3krit'
     7     },
     8     'users': {
     9         'NAME': 'user_data',
    10         'ENGINE': 'django.db.backends.mysql',
    11         'USER': 'mysql_user',
    12         'PASSWORD': 'priv4te'
    13     }
    14 }

    同步数据库:

    1 $ ./manage.py migrate
    2 $ ./manage.py migrate --database=users

    数据库路由,假设有如下多个数据库:

     1 DATABASES = {
     2     'auth_db': {
     3         'NAME': 'auth_db',
     4         'ENGINE': 'django.db.backends.mysql',
     5         'USER': 'mysql_user',
     6         'PASSWORD': 'swordfish',
     7     },
     8     'primary': {
     9         'NAME': 'primary',
    10         'ENGINE': 'django.db.backends.mysql',
    11         'USER': 'mysql_user',
    12         'PASSWORD': 'spam',
    13     },
    14     'replica1': {
    15         'NAME': 'replica1',
    16         'ENGINE': 'django.db.backends.mysql',
    17         'USER': 'mysql_user',
    18         'PASSWORD': 'eggs',
    19     },
    20     'replica2': {
    21         'NAME': 'replica2',
    22         'ENGINE': 'django.db.backends.mysql',
    23         'USER': 'mysql_user',
    24         'PASSWORD': 'bacon',
    25     },
    26 }

    路由的实现如下:

     1 class AuthRouter(object):
     2     """
     3     A router to control all database operations on models in the
     4     auth application.
     5     """
     6     def db_for_read(self, model, **hints):
     7         """
     8         Attempts to read auth models go to auth_db.
     9         """
    10         if model._meta.app_label == 'auth':
    11             return 'auth_db'
    12         return None
    13 
    14     def db_for_write(self, model, **hints):
    15         """
    16         Attempts to write auth models go to auth_db.
    17         """
    18         if model._meta.app_label == 'auth':
    19             return 'auth_db'
    20         return None
    21 
    22     def allow_relation(self, obj1, obj2, **hints):
    23         """
    24         Allow relations if a model in the auth app is involved.
    25         """
    26         if obj1._meta.app_label == 'auth' or 
    27            obj2._meta.app_label == 'auth':
    28            return True
    29         return None
    30 
    31     def allow_migrate(self, db, app_label, model=None, **hints):
    32         """
    33         Make sure the auth app only appears in the 'auth_db'
    34         database.
    35         """
    36         if app_label == 'auth':
    37             return db == 'auth_db'
    38         return None
     1 import random
     2 
     3 class PrimaryReplicaRouter(object):
     4     def db_for_read(self, model, **hints):
     5         """
     6         Reads go to a randomly-chosen replica.
     7         """
     8         return random.choice(['replica1', 'replica2'])
     9 
    10     def db_for_write(self, model, **hints):
    11         """
    12         Writes always go to primary.
    13         """
    14         return 'primary'
    15 
    16     def allow_relation(self, obj1, obj2, **hints):
    17         """
    18         Relations between objects are allowed if both objects are
    19         in the primary/replica pool.
    20         """
    21         db_list = ('primary', 'replica1', 'replica2')
    22         if obj1._state.db in db_list and obj2._state.db in db_list:
    23             return True
    24         return None
    25 
    26     def allow_migrate(self, db, app_label, model=None, **hints):
    27         """
    28         All non-auth models end up in this pool.
    29         """
    30         return True

    最后设置:

    1 DATABASE_ROUTERS = ['path.to.AuthRouter', 'path.to.PrimaryReplicaRouter']

    此外,可以使用using属性手动操作Database。

    ———————————————————————————————————————————————————————————————————————————————————————————

    14. 表空间(Tablespace)及数据库接入优化(Database access optimization)

    使用表空间可以优化数据库运行。略过。

    数据库接入优化。略过。

    -- The End -- 

  • 相关阅读:
    结对作业
    小学算术题四则运算(升级)
    自动生成小学四则运算题目(Python实现)
    《基于CMMI的软件工程及实训指导》第一章 软件工程基础
    使用 python 进行微信好友分析
    中国大学排名
    python小程序测试
    爬虫测试
    体育竞技分析

  • 原文地址:https://www.cnblogs.com/py-drama/p/4600969.html
Copyright © 2011-2022 走看看