python16_day24【restful、crm表构、认证】
一、restful
1. pip install djangorestframework
2.settings.py
1 INSTALLED_APPS = ( 2 ... 3 'rest_framework', 4 )
1 REST_FRAMEWORK = { 2 # Use Django's standard `django.contrib.auth` permissions, 3 # or allow read-only access for unauthenticated users. 4 'DEFAULT_PERMISSION_CLASSES': [ 5 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly' 6 ] 7 }
3.urls.py
1 from django.conf.urls import url, include 2 from django.contrib.auth.models import User 3 from rest_framework import routers, serializers, viewsets 4 5 # Serializers define the API representation. 6 class UserSerializer(serializers.HyperlinkedModelSerializer): 7 class Meta: 8 model = User
depth = 2 9 fields = ('url', 'username', 'email', 'is_staff') 10 11 # ViewSets define the view behavior. 12 class UserViewSet(viewsets.ModelViewSet): 13 queryset = User.objects.all() 14 serializer_class = UserSerializer 15 16 # Routers provide an easy way of automatically determining the URL conf. 17 router = routers.DefaultRouter() 18 router.register(r'users', UserViewSet) 19 20 # Wire up our API using automatic URL routing. 21 # Additionally, we include login URLs for the browsable API. 22 urlpatterns = [ 23 url(r'^', include(router.urls)), 24 url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) 25 ]
4.http://127.0.0.1:8000/users/
5.自定义views
根据上面基础,深入自定义views
1 urlpatterns = [ 2 url(r'^', include(router.urls)), 3 url(r'^eventlog_list/$', eventlog_list), 4 url(r'^eventlog_detail/(\d+)/$', eventlog_detail), 5 url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')) 6 ]
1 @api_view(['GET', 'POST']) #只允许POST、GET 2 def eventlog_list(request): 3 """ 4 List all snippets, or create a new snippet. 5 """ 6 if request.method == 'GET': 7 eventlogs = models.EventLog.objects.all() 8 serializer = rest_searilizers.EventLogSerializer(eventlogs, many=True) 9 return Response(serializer.data) 10 11 elif request.method == 'POST': 12 print("request", request.data) 13 serializer =rest_searilizers.EventLogSerializer(data=request.data) 14 if serializer.is_valid(): 15 serializer.save() 16 return Response(serializer.data, status=status.HTTP_201_CREATED) 17 return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) 18 19 20 @api_view(['GET','PUT']) 21 @csrf_exempt # 放开这个视图的CSRF检查 22 def eventlog_detail(request, pk): 23 """ 24 Retrieve, update or delete a code eventlog. 25 """ 26 try: 27 eventlog_obj = models.EventLog.objects.get(pk=pk) 28 except models.EventLog.DoesNotExist: 29 return HttpResponse(status=404) 30 31 if request.method == 'GET': 32 serializer = rest_searilizers.EventLogSerializer(eventlog_obj) 33 return JsonResponse(serializer.data) 34 35 elif request.method == 'PUT': 36 print(request) 37 data = JSONParser().parse(request) 38 serializer = rest_searilizers.EventLogSerializer(eventlog_obj, data=data) 39 if serializer.is_valid(): 40 serializer.save() 41 return JsonResponse(serializer.data) 42 return JsonResponse(serializer.errors, status=400) 43 44 elif request.method == 'DELETE': 45 eventlog_obj.delete() 46 return HttpResponse(status=204)
二、自定义认证
方式一:继承User表,一对一增加自己想要的字段
from django.contrib.auth.models import User class UserInfo(models.Model): username = models.OneToOneField(User)
方式二:继承abstractbaseuser
1.settings.py 指定系统认证不再是User表改成UserProfile
AUTH_USER_MODEL = 'crm.UserProfile'
2.models.py 继承基类新的User表,即UserProfile. 还有一个管理类
1 from django.db import models 2 3 # Create your models here. 4 from django.contrib.auth.models import ( 5 BaseUserManager, AbstractBaseUser 6 # BaseUserManager email规范设置和密码基本设置规则 7 # AbstractBaseUser 真正的用户名 密码 验证 8 ) 9 10 # ################如果用User model 11 # 1、必须有一个唯一的字段可被用于识别目的 12 # 2、full 和 short的名字 13 # 继承AbstractBaseUser 这个是核心 14 # 有了这个还必须要有一个自定管理器 15 # 如果和User字段和默认的一致的话,直接使用UserManager就可以了,如果user定义了不同的字段 16 # 需要自定义一个管理器,它继承BaseUserManager 并提供2个额外的方法: 17 18 19 class UserProfileManager(BaseUserManager): 20 def create_user(self, email, name, password=None): 21 """ 22 Creates and saves a User with the given email, name and password. 23 """ 24 '''email是唯一标识,没有会报错''' 25 if not email: 26 raise ValueError('Users must have an email address') 27 28 user = self.model( 29 email=self.normalize_email(email), # 检查email规则 30 name=name, 31 ) 32 # AbstractBaseUser set_password == > make_password == > 加盐 hash 33 user.set_password(password) # 检测密码合理性 34 user.save(using=self._db) # 保存密码 35 return user 36 37 def create_superuser(self, email, name, password): 38 """ 39 Creates and saves a superuser with the given email, name and password. 40 """ 41 user = self.create_user(email, 42 password=password, 43 name=name 44 ) 45 user.is_admin = True # 比创建用户多的一个字段 46 user.save(using=self._db) 47 return user 48 49 50 class UserProfile(AbstractBaseUser): 51 email = models.EmailField( 52 verbose_name='email address', 53 max_length=255, 54 unique=True, 55 ) 56 name = models.CharField(max_length=32) 57 is_active = models.BooleanField(default=True) 58 is_admin = models.BooleanField(default=False) 59 60 objects = UserProfileManager() # 会用到 get_by_natural_key 不然会报 61 62 USERNAME_FIELD = 'email' # 默认的用户名,对于自定义的用户模型,用USERNAME_FIELD 标识 63 REQUIRED_FIELDS = ['name'] # 通过createsuperuser管理命令创建一个用户时,用于提示的一个字段名称列表 64 65 def get_full_name(self): 66 # The user is identified by their email address 67 return self.email 68 69 def get_short_name(self): 70 # The user is identified by their email address 71 return self.email 72 73 def __str__(self): # __unicode__ on Python 2 74 return self.email 75 76 '''django自带后台权限控制,对哪些表有查看权限等''' 77 def has_perm(self, perm, obj=None): 78 "Does the user have a specific permission?" 79 # Simplest possible answer: Yes, always 80 return True 81 82 '''用户是否有权限看到app''' 83 def has_module_perms(self, app_label): 84 "Does the user have permissions to view the app `app_label`?" 85 # Simplest possible answer: Yes, always 86 return True 87 88 @property 89 def is_staff(self): # 用户管理网站权限 90 "Is the user a member of staff?" 91 # Simplest possible answer: All admins are staff 92 return self.is_admin
3.admin.py 能过管理管理UserProfile一些配置
1 # 如果你想在admin控制台上面看到用户的表,需要在admin.py增加这些 2 from crm import models 3 from django import forms 4 from django.contrib import admin 5 from django.contrib.auth.models import Group 6 from django.contrib.auth.admin import UserAdmin as BaseUserAdmin 7 from django.contrib.auth.forms import ReadOnlyPasswordHashField 8 from crm.models import UserProfile 9 10 11 class UserCreationForm(forms.ModelForm): 12 """A form for creating new users. Includes all the required 13 fields, plus a repeated password.""" 14 password1 = forms.CharField(label='Password', widget=forms.PasswordInput) 15 password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput) 16 17 class Meta: 18 model = UserProfile 19 fields = ('email', 'name') 20 21 def clean_password2(self): 22 # Check that the two password entries match 23 password1 = self.cleaned_data.get("password1") 24 password2 = self.cleaned_data.get("password2") 25 if password1 and password2 and password1 != password2: 26 raise forms.ValidationError("Passwords don't match") 27 return password2 28 29 def save(self, commit=True): 30 # Save the provided password in hashed format 31 user = super(UserCreationForm, self).save(commit=False) 32 user.set_password(self.cleaned_data["password1"]) 33 if commit: 34 user.save() 35 return user 36 37 38 class UserChangeForm(forms.ModelForm): 39 """A form for updating users. Includes all the fields on 40 the user, but replaces the password field with admin's 41 password hash display field. 42 """ 43 password = ReadOnlyPasswordHashField() 44 45 class Meta: 46 model = UserProfile 47 fields = ('email', 'password', 'name', 'is_active', 'is_admin') 48 49 def clean_password(self): 50 # Regardless of what the user provides, return the initial value. 51 # This is done here, rather than on the field, because the 52 # field does not have access to the initial value 53 return self.initial["password"] 54 55 56 class UserAdmin(BaseUserAdmin): 57 # 添加和更改用户实例的表单 58 # 以前是ModelAdmin 59 # The forms to add and change user instances 60 form = UserChangeForm 61 add_form = UserCreationForm 62 63 # The fields to be used in displaying the User model. 64 # These override the definitions on the base UserAdmin 65 # that reference specific fields on auth.User. 66 list_display = ('email', 'name', 'is_admin') # 这个和以前一样,显示一条数据这3个字段 67 list_filter = ('is_admin',) # 用这个字段过滤 68 fieldsets = ( # 点击进入,显示详细 69 ('email passwd', {'fields': ('email', 'password')}), # email passwd是蓝色条框 70 ('Personal info', {'fields': ('name',)}), 71 ('Permissions', {'fields': ('is_admin',)}), 72 ) 73 # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin 74 # overrides get_fieldsets to use this attribute when creating a user. 75 add_fieldsets = ( # 增加用户时显示详细 76 ('增加', { 77 'classes': ('wide',), 78 'fields': ('email', 'name', 'password1', 'password2')} 79 ), 80 ) 81 search_fields = ('email',) # 查询字段 82 ordering = ('email',) # 排序字段 83 filter_horizontal = () # 水平和垂直 84 85 # 86 admin.site.register(models.UserProfile, UserAdmin) 87 admin.site.unregister(Group)
项目:https://github.com/willianflasky/growup/tree/master/s16/homework/day24_restful/LuffyCRM