微信号:omret-django

介绍:每日推送django、python相关技术文档,技术趣文等.

关于Django的笔试题

2016-03-21 21:19 Django

一、抽象继承:


  顺便复习OOP思想,继承是面向对象的大前提╮(╯▽╰)╭,抽象类,之所以被创建是用来被继承的;一个类如果包含任何一种抽象方法,那么它就是抽象类;抽象方法一定要在子类中被复写;在继承关系中,抽象类永远在树枝节点上……扯远了,而且对于Python来说,已经没有这么多约束了。


  回到Django的Model,也一样,当我们需要某些公共方法字段时,就需要一个父类为其他子类服务,这个父类没有manager,Django也不为这个类创建表,这种继承的定义方法如下:

  class Animal(models.Model):

  name = models.CharField(max_length=50)

  age = models.PositiveIntegerField()

  # 下面这句决定了Animal是一个抽象类/Model

  class Meta:

  abstract = True

  class Human(Animal):

  kind_hearted = models.BooleanField()

  sex = models.CharField('sex', choices=(('m','male'), ('f', 'female')), max_length=1)

  #...


  上例中,我们的Human子model中,自然包含了name和age的字段,但是Animal不能作为正常model使用,由于没有manager,所以也不能实例化、保存。在子类中,不可以建立与这个抽象父类中的相同的字段,Django表示对报错负责。


  二、正常的继承,多重继承,Joined映射


  和抽象继承的主要区别是父类这时也可以拥有数据库表了,并且不在身为存储公共信息的抽象类了,父类也可以进行实例化,查询等操作了。

  class Country(models.Model):

  name = models.CharField(max_length=10)

  #...

  class Province(Country):

  return = models.BooleanField()

  #...


  三、代理

  即在子类中只能增加方法,而不能增加属性,在不影响父类数据存储的前提下,使子类继承父类,此时子类称为父类的“代理”。例如:

  from django.contrib.auth.models import User

  class Person(User):

  # this makes a class proxy

  proxy = True

  def can_dance(self):

  return True

  # both Yellow and Black can_dance :)

  class Yellow(Person):

  hometown = models.CharField(max_length=30)

  class Black(Person)

  tribe_name = models.CharField(max_length=100)


  我们为Person类增加了一个方法,可以跳舞,并且保持了User的数据字段的不变。


  Django的Queryset是什么,objects是什么,objects在哪里可以定义。


  query + set,已经能猜出大概,它对应着数据库中的若干条记录。

  例如有一个叫做Order的模型,在project的根目录下进入shell进行操作:

  $python manage.py shell

  >>>from app.order.models import Order

  >>>type(Order.objects)

  >>>

  >>>order = Order.objects.all()

  >>>type(order)


  上述方法很常用,看继承关系去理解Queryset和objets。objects是每个Model默认的manager类,通过manager的方法(也可通过QuerySet的方法得到,当然QuerySet也来自于manager),得到相应的Queryset,用以对数据库模型字段进行更多的操作。


  objects(manager)方法可以自定义添加,也可以直接赋值覆盖掉默认的管理方法。


  试着添加一个新的管理器的步骤是这样,首先定义一个manager类继承自models.Manager,并在其中对self进行操作,如下:

  # new manager

  class OrderManager(models.Manager):

  def title_count(self, keyword):

  return self.filter(title__icontains=keyword).count()

  class Order(models.Models):

  title = models.CharField(max_length=100)

  # ...

  #objects = models.Manager()

  objects = OrderManager()

  def __unicode__(self):

  return self.title


  上述例子中我们把OrderManager赋值给了objects,替换了默认的管理器。


  tips:如果增加了新的管理器,且没有替换掉默认管理器,那么默认管理器需要显式的声明出来才可以使用。


  Django中查询queryset时什么情况下用Q?


  在进行相对复杂的查询时,使用django.db.models.Q对象。


  例如需要进行复合条件的查询的SQL语句如下:

  SELECT * FROM order WHERE id BETWEEN 20 ADN 100 AND(num <= '20' or num >= '30');


  使用Q就可以写成:

  from django.db.models import Q

  from login.models import Order

  #...

  Order.objects.get(

  Q(id >= 20) & (id <= 100),

  Q(num <= 20) | (num >= 30)

  )


  Django中想验证表单提交是否格式正确需要用到Form中的哪个函数?


  is_valid()函数方法,用于检查表单提交是否正确。


  Django取消级联删除


  这个文档写的比较清楚:

  user = models.ForeignKey(User, blank=True, null=True, on_delete=models.SET_NULL)


  并且SET_NULL只有在null为True的时候,才可以使用。


  Django中如何在Model保存前做一定的固定操作,比如写一句日志?


  关键词: 信号


  利用Django的Model的Signal Dispatcher, 通过django.db.models.signals.pre_save()方法,在事件发生前,发射触发信号,这一切都被调度中的receiver方法深藏功与名的保存了。


  信号的处理一般都写在Model中,举个例子:

  import logging

  from django.db import models

  from django.db.models.signals import pre_save

  from django.dispatch import receiver

  class Order(models.Model):

  # ...

  logger = logging.getLogger(__name__)

  @receiver(pre_save, sender=Order)

  def pre_save_handler(sender, **kwargs):

  # 我们可以在Order这个Model保存之前尽情调戏了:)

  logger.debug("{},{}".format(sender, **kwargs))

  print 'fuck universe'


  这样应该就实现了题中的要求,类似的方法还有比如pre_init是在Model实例之前会触发,post_init在实例之后触发,同理就是pre_save和post_save了。


转载自:应届毕业生


 
Django 更多文章 Django框架简介 django-MySQL数据库 如何实现 C/C++ 与 Python 的通信? Django教程1-MVC Python哪些可以代替递归的算法?
猜您喜欢 汉堡包菜单在大屏设备上的可用性问题 做为家长,我期待真正的创客教育(一) 如何正确配置 Nginx + PHP 阿里百川与极客邦科技达成战略合作 Weex宣布开源 程序员过的开心的方法