[关闭]
@BurdenBear 2017-12-25T15:51:40.000000Z 字数 3841 阅读 436

Django 面试题

未分类


Model

  1. Django的Model的继承有几种形式,分别是什么?

    • 抽象继承:
      顺便复习OOP思想,继承是面向对象的大前提╮(╯▽╰)╭,抽象类,之所以被创建是用来被继承的;一个类如果包含任何一种抽象方法,那么它就是抽象类;抽象方法一定要在子类中被复写;在继承关系中,抽象类永远在树枝节点上……扯远了,而且对于Python来说,已经没有这么多约束了。
      回到Django的Model,也一样,当我们需要某些公共方法字段时,就需要一个父类为其他子类服务,这个父类没有manager,Django也不为这个类创建表,这种继承的定义方法如下:
      1. class Animal(models.Model):
      2. name = models.CharField(max_length=50)
      3. age = models.PositiveIntegerField()
      4. # 下面这句决定了Animal是一个抽象类/Model
      5. class Meta:
      6. abstract = True
      7. class Human(Animal):
      8. kind_hearted = models.BooleanField()
      9. sex = models.CharField('sex', choices=(('m','male'), ('f', 'female')), max_length=1)
      10. #...

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

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

      1. class Country(models.Model):
      2. name = models.CharField(max_length=10)
      3. #...
      4. class Province(Country):
      5. return = models.BooleanField()
      6. #...
    • 代理(这种我之前也没用到过,感觉不怎么常用)
      即在子类中只能增加方法,而不能增加属性,在不影响父类数据存储的前提下,使子类继承父类,此时子类称为父类的“代理”。例如:

      1. from django.contrib.auth.models import User
      2. class Person(User):
      3. # this makes a class proxy
      4. proxy = True
      5. def can_dance(self):
      6. return True
      7. # both Yellow and Black can_dance :)
      8. class Yellow(Person):
      9. hometown = models.CharField(max_length=30)
      10. class Black(Person)
      11. tribe_name = models.CharField(max_length=100)
  2. Django的Queryset是什么,objects是什么,objects在哪里可以定义。
    query + set,已经能猜出大概,它对应着数据库中的若干条记录。
    例如有一个叫做Order的模型,在project的根目录下进入shell进行操作:

    1. $python manage.py shell
    2. >>>from app.order.models import Order
    3. >>>type(Order.objects)
    4. <class 'django.db.models.models.manager.Manager'>
    5. >>>
    6. >>>order = Order.objects.all()
    7. >>>type(order)
    8. <class 'django.db.models.query.QuerySet'>

    上述方法很常用,看继承关系去理解Queryset和objets。objects是每个Model默认的manager类,通过manager的方法(也可通过QuerySet的方法得到,当然QuerySet也来自于manager),得到相应的Queryset,用以对数据库模型字段进行更多的操作。
    objects(manager)方法可以自定义添加,也可以直接赋值覆盖掉默认的管理方法。
    试着添加一个新的管理器的步骤是这样,首先定义一个manager类继承自models.Manager,并在其中对self进行操作,如下:

    1. # new manager
    2. class OrderManager(models.Manager):
    3. def title_count(self, keyword):
    4. return self.filter(title__icontains=keyword).count()
    5. class Order(models.Models):
    6. title = models.CharField(max_length=100)
    7. # ...
    8. #objects = models.Manager()
    9. objects = OrderManager()
    10. def __unicode__(self):
    11. return self.title

    上述例子中我们把OrderManager赋值给了objects,替换了默认的管理器。
    tips:如果增加了新的管理器,且没有替换掉默认管理器,那么默认管理器需要显式的声明出来才可以使用。

  3. Django中查询queryset时什么情况下用Q?
    在进行相对复杂的查询时,使用django.db.models.Q对象。
    例如需要进行复合条件的查询的SQL语句如下:

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

    使用Q就可以写成:

    1. from django.db.models import Q
    2. from login.models import Order
    3. #...
    4. Order.objects.get(Q(id__gte=20) & Q(id__lte=100) & (Q(num__lte =20) | (num__gte= 30))
  4. Django的queryset在什么时候会真正向数据库发起请求
    https://docs.djangoproject.com/en/1.11/ref/models/querysets/#when-querysets-are-evaluated

  5. Django中如何在Model保存前做一定的固定操作,比如写一句日志?
    关键词: 信号
    利用Django的Model的Signal Dispatcher, 通过django.db.models.signals.pre_save()方法,在事件发生前,发射触发信号,这一切都被调度中的receiver方法深藏功与名的保存了。
    信号的处理一般都写在Model中,举个例子:

    1. import logging
    2. from django.db import models
    3. from django.db.models.signals import pre_save
    4. from django.dispatch import receiver
    5. class Order(models.Model):
    6. # ...
    7. logger = logging.getLogger(__name__)
    8. @receiver(pre_save, sender=Order)
    9. def pre_save_handler(sender, **kwargs):
    10. # 我们可以在Order这个Model保存之前尽情调戏了:)
    11. logger.debug("{},{}".format(sender, **kwargs))
    12. print 'fuck universe'

View

  1. 简述FormView处理HTTPRequest的过程
    获取请求内容及url参数——>
    • 如果是get请求,实例化空表单,调用get_context_data,默认context["form"]=form——>寻找template模板->由context渲染模板返回;
    • 如果是post请求,由request body里的数据实例化表单,调用form.is_valid方法,如果为真,调用formview.form_valid;如果为假,调用formview.form_invalid,一般会根据form.errors重新渲染模板返回。

Other

  1. Django中如何读取和保存session,整个session的运行机制是什么。
    说到session的运行机制,就一定要先说一下cookie这一段信息。一般情况下cookies都是我们的浏览器生成的(显然可以人为修改),用于服务器对户进行筛选和维护,但是这个听上去很好吃的东西,能存的东西有点少而且容易被别人利用。这时候基于cookies的session的意义就比较明显了,在客户端的cookies中我们只保存session id,而将完整信息以加密信息的形式保存到服务器端,这样服务器可以根据session id相对安全的在数据库中查询用户的更细致的信息和状态。
    在Django中session和cookies的操作方法一样,如下:

    1. # 保存session
    2. request.session['order_id'] = order_id
    3. # 删除session
    4. del request.session['order_id']
    5. # 读取session
    6. session.get('order_id', False)
  2. 用过django第三方模块,完成了什么工作。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注