最近在网易云课堂学习一门django高级实战教程,本文是学习课时1四、15的一些笔记html
继承BaseUserManager
和AbstractBaseUser
,指定AUTH_USER_MODEL
配置项python
看一下cookiecutter给咱们生成的项目结构下的mydjango/users/models.py
自定义的User继承了AbstractUsergit
class User(AbstractUser): # First Name and Last Name do not cover name patterns # around the globe. name = CharField(_("Name of User"), blank=True, max_length=255) def get_absolute_url(self): return reverse("users:detail", kwargs={"username": self.username})
AbstractUser里的定义(~/anaconda3/envs/djg22env/lib/python3.7/site-packages/django/contrib/auth/base.py
)web
class AbstractUser(AbstractBaseUser, PermissionsMixin): """ An abstract base class implementing a fully featured User model with admin-compliant permissions. Username and password are required. Other fields are optional. """ username_validator = UnicodeUsernameValidator() username = models.CharField( _('username'), max_length=150, unique=True, help_text=_('Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.'), validators=[username_validator], error_messages={ 'unique': _("A user with that username already exists."), }, ) first_name = models.CharField(_('first name'), max_length=30, blank=True) last_name = models.CharField(_('last name'), max_length=150, blank=True) email = models.EmailField(_('email address'), blank=True) is_staff = models.BooleanField( _('staff status'), default=False, help_text=_('Designates whether the user can log into this admin site.'), ) is_active = models.BooleanField( _('active'), default=True, help_text=_( 'Designates whether this user should be treated as active. ' 'Unselect this instead of deleting accounts.' ), ) date_joined = models.DateTimeField(_('date joined'), default=timezone.now) objects = UserManager() EMAIL_FIELD = 'email' USERNAME_FIELD = 'username' REQUIRED_FIELDS = ['email'] class Meta: verbose_name = _('user') verbose_name_plural = _('users') abstract = True def clean(self): super().clean() self.email = self.__class__.objects.normalize_email(self.email) def get_full_name(self): """ Return the first_name plus the last_name, with a space in between. """ full_name = '%s %s' % (self.first_name, self.last_name) return full_name.strip() def get_short_name(self): """Return the short name for the user.""" return self.first_name def email_user(self, subject, message, from_email=None, **kwargs): """Send an email to this user.""" send_mail(subject, message, from_email, [self.email], **kwargs)
已经有username
,first_name
,last_name
,email
,is_staff
,is_active
,date_joined
这些字段,因此咱们本身定义User的时候,继承AbstractUser
,而后加入另外的字段就好了。再经过config/settings/base.py
中的AUTH_USER_MODEL = "users.User"
将本身定义的User指定上去
本来默认的User是这个
(~/anaconda3/envs/djg22env/lib/python3.7/site-packages/django/contrib/auth/base.py
)数据库
class User(AbstractUser): """ Users within the Django authentication system are represented by this model. Username and password are required. Other fields are optional. """ class Meta(AbstractUser.Meta): swappable = 'AUTH_USER_MODEL'
继承CreateView
,UpdateView
,ListView
,DetailView
,DeleteView
官方文档-基于类的视图django
基于类的视图提供另外一种将视图实现为 Python 对象而不是函数的方法。它们不能替代基于函数的视图,但与基于函数的视图相比,它们是有某些不一样和优点的。
与特定的 HTTP 方法(GET, POST, 等等)关联的代码组织能经过单独的方法替代条件分支来解决。
面向对象技术(好比 mixins 多重继承)可用于将代码分解为可重用组件。后端
基于类的视图容许你使用不一样的类实例方法响应不一样 HTTP 请求方法缓存
from django.http import HttpResponse from django.views import View class MyView(View): def get(self, request): # <view logic> return HttpResponse('result')
使用基于类的视图处理表单bash
from django.http import HttpResponseRedirect from django.shortcuts import render from django.views import View from .forms import MyForm class MyFormView(View): form_class = MyForm initial = {'key': 'value'} template_name = 'form_template.html' def get(self, request, *args, **kwargs): form = self.form_class(initial=self.initial) return render(request, self.template_name, {'form': form}) def post(self, request, *args, **kwargs): form = self.form_class(request.POST) if form.is_valid(): # <process form cleaned data> return HttpResponseRedirect('/success/') return render(request, self.template_name, {'form': form})
具体请参考官方文档
Django 附带一些内置的通用视图,它们生成列表和对象的详情视图极为方便。服务器
# models.py from django.db import models 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() class Meta: ordering = ["-name"] def __str__(self): return self.name class Author(models.Model): salutation = models.CharField(max_length=10) name = models.CharField(max_length=200) email = models.EmailField() headshot = models.ImageField(upload_to='author_headshots') def __str__(self): return self.name class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField('Author') publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE) publication_date = models.DateField()
# views.py from django.views.generic import ListView from books.models import Publisher class PublisherList(ListView): model = Publisher
# urls.py from django.urls import path from books.views import PublisherList urlpatterns = [ path('publishers/', PublisherList.as_view()), ]
这就是咱们须要编写的全部代码。尽管咱们仍然须要编写一个模板。咱们能够给视图添加 template_name
属性来告诉视图使用哪一个模板,但若是没有明确的模板,Django 将从对象名称中推断一个。在这个例子中,推断模板将是 "books/publisher_list.html"
—— “books” 部分来自定义模型的 app 名称,而 “publisher” 必须是模型名称的小写。
{% extends "base.html" %} {% block content %} <h2>Publishers</h2> <ul> {% for publisher in object_list %} <li>{{ publisher.name }}</li> {% endfor %} </ul> {% endblock %}
根据不一样的场合(开发、测试、部署)配置不一样的选项
编写测试用例,生成测试覆盖度报告
现在,软件一般会做为一种服务来交付,它们被称为网络应用程序,或软件即服务(SaaS)。12-Factor 为构建以下的 SaaS 应用提供了方法论: