登录,认证,ContentType组件,序列化增删改查查(my)

序列化增删改查查                

APP01下:

1,在models.py创建表,数据库迁移,把本地数据库拉过去

from django.db import models

__all__ = ["Book","Publisher","Author"]

class Book(models.Model):
    """
    书籍列表
    """
    title = models.CharField(verbose_name="书名",max_length=32)
    pub_time = models.DateField(verbose_name="出版时间",)
    choices = ((1,"武侠"), (2, "言情"), (3, "科幻"), )
    category = models.IntegerField(verbose_name="分类",choices=choices)
    publisher = models.ForeignKey(verbose_name="出版社名称",to="Publisher",max_length=32,null=True)
    authors = models.ManyToManyField(verbose_name="作者",to="Author")

    class Meta:
        verbose_name_plural = "书籍列表"  #在admin里显示中文

    def __str__(self):
        return self.title




class Publisher(models.Model):
    """
    出版社列表
    """
    title = models.CharField(verbose_name="出版社名称",max_length=32)

    class Meta:
        verbose_name_plural = "出版社列表"   #在admin里显示中文

    def __str__(self):
        return self.title



class Author(models.Model):
    """
    用户表
    """
    name = models.CharField(verbose_name="用户名",max_length=32)
    pwd = models.CharField(verbose_name="用户密码",max_length=64)
    token = models.UUIDField(verbose_name="验证码",null=True,blank=True)


    class Meta:
        verbose_name_plural = "用户表"  #在admin里显示中文


    def __str__(self):
        return self.name
View Code

2,在admin.py注册,在admin页面显示添加数据-------》创建超级用户--》添加数据

from django.contrib import admin

from . import models

for table in models.__all__:
    admin.site.register(getattr(models,table))




#或者
# from app01.models import Book,Publisher,Author
#
# admin.site.register(Book)
# admin.site.register(Publisher)
# admin.site.register(Author)
View Code

3,创建序列化器serializer.py

 正序或反序的时候choices类型,一对多或者多对多,序列化的时候不显示,所以需要设置

# 正序或反序的时候choices类型,一对多或者多对多,序列化的时候不显示,所以需要设置

from rest_framework import serializers
from app01.models import Book

class BookSerializer(serializers.ModelSerializer):
    #正序和反序列化不同的字段

    #重定义新的字段正序列化走
    # SerializerMethodField方法必须得用钩子函数获取新值  read_only=True正序走
    category_display = serializers.SerializerMethodField(read_only=True)
    publisher_info = serializers.SerializerMethodField(read_only=True)
    authors_info = serializers.SerializerMethodField(read_only=True)


    #获取表里的字段信息把获取到的值返回给SerializerMethodField方法赋值给新变量
    def get_category_display(self,obj):   #choices类型
        return obj.get_category_display()

    def get_publisher_info(self,obj):  #外键

        return {"id":obj.publisher.id,"title":obj.publisher.title}

    def get_authors_info(self, obj):  #多对多
        # 列表生成式循环获得每个作者信息
        return [{"id": author.id, "name": author.name} for author in obj.authors.all()]

    class Meta:
        model = Book  #获取的模型

        fields = "__all__"  #获取Book里的所有字段
        #设置反序列化走
        extra_kwargs = {"category":{"write_only":True},"publisher":{"write_only":True},
                        "authors":{"write_only":True}}
View Code

4,urls.py

from django.conf.urls import url
from django.contrib import admin
from app01.views import BookView,BookEditView


urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r"^books",BookView.as_view()),
    url(r"^book/(?P<pk>\d+)",BookEditView.as_view())
]
View Code

5,views.py

from .models import Book
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book,Author
from app01.serializer import BookSerializer

import uuid

class BookView(APIView):

    def get(self,request):
        #查看所有的图书
        queryset = Book.objects.all()
        ser_obj = BookSerializer(queryset,many=True)#转序列化
        return Response(ser_obj.data)#序列化后的数据

    def post(self,request):
        #新增图书
        ser_obj = BookSerializer(data=request.data)
        if ser_obj.is_valid():  #如果通过校验
            ser_obj.save()
            return Response(ser_obj.validated_data)

class BookEditView(APIView):
    #查看单条数据
    def get(self,request,pk):
        book_obj = Book.objects.filter(id=pk).first()
        ser_obj = BookSerializer(book_obj)  #转序列化
        return Response(ser_obj.data)  #序列化后的数据
    #更新数据
    def put(self,request,pk):
        book_obj = Book.objects.filter(id=pk).first()
        #instance=book_obj原来的数据,data=request.data新的数据,partial=True允许部分更新
        ser_obj = BookSerializer(instance=book_obj,data=request.data,partial=True)
        if ser_obj.is_valid():  #检验成功
            ser_obj.save()
            return Response(ser_obj.validated_data)#通过校验的数据
        else:
            return Response(ser_obj.errors)  #返回错误信息

    #删除
    def delete(self,request,pk):
        book_obj = Book.objects.filter(id=pk).first()
        if not book_obj:
            return Response({"code":1001,"error":"删除的数据不存在"})  #code返回的状态码
        else:
            book_obj.delete()
            return Response("")
View Code

6,一定要注册settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    'rest_framework',
]
View Code

 查询所有:http://127.0.0.1:8000/books, 查询单条:http://127.0.0.1:8000/book/3

登录                   

 urls.py:

from django.conf.urls import url
from django.contrib import admin
from app01.views import BookView,BookEditView,LoginView


urlpatterns = [
    url(r'^admin/', admin.site.urls),

    url(r"^books",BookView.as_view()),
    url(r"^book/(?P<pk>\d+)",BookEditView.as_view()),

    #登录
    url(r"^login",LoginView.as_view())
]
View Code

views.py

from .models import Book
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book,Author
from app01.serializer import BookSerializer
from .authentication import MyAuth

import uuid

class BookView(APIView):

    

    def get(self,request):
        #查看所有的图书
        queryset = Book.objects.all()
        ser_obj = BookSerializer(queryset,many=True)#转序列化
        return Response(ser_obj.data)#序列化后的数据

    def post(self,request):
        #新增图书
        ser_obj = BookSerializer(data=request.data)
        if ser_obj.is_valid():  #如果通过校验
            ser_obj.save()
            return Response(ser_obj.validated_data)

class BookEditView(APIView):
    #查看单条数据
    def get(self,request,pk):
        book_obj = Book.objects.filter(id=pk).first()
        ser_obj = BookSerializer(book_obj)  #转序列化
        return Response(ser_obj.data)  #序列化后的数据
    #更新数据
    def put(self,request,pk):
        book_obj = Book.objects.filter(id=pk).first()
        #instance=book_obj原来的数据,data=request.data新的数据,partial=True允许部分更新
        ser_obj = BookSerializer(instance=book_obj,data=request.data,partial=True)
        if ser_obj.is_valid():  #检验成功
            ser_obj.save()
            return Response(ser_obj.validated_data)#通过校验的数据
        else:
            return Response(ser_obj.errors)  #返回错误信息

    #删除
    def delete(self,request,pk):
        book_obj = Book.objects.filter(id=pk).first()
        if not book_obj:
            return Response({"code":1001,"error":"删除的数据不存在"})  #code返回的状态码
        else:
            book_obj.delete()
            return Response("")


#登录
class LoginView(APIView):
    def post(self,request):
        #获取前端传过来的用户名和密码
        username = request.data.get("username","")
        pwd = request.data.get("pwd","")
        #验证用户登录是否成功
        user_obj = Author.objects.filter(name=username,pwd=pwd).first()
        if not user_obj:
            return Response("用户名或密码不正确")
        token = uuid.uuid4()
        user_obj.token = token
        user_obj.save()
        return Response(token)
View Code

 

前后端分离,登录没有页面

 认证        

 创建authentication.py写认证类:

from rest_framework import authentication
from rest_framework.exceptions import AuthenticationFailed
from .models import Author

class MyAuth(authentication.BaseAuthentication):
    def authenticate(self, request):
        #获取前端传过来的token
        token = request.query_params.get("token","")
        if not token:
            raise AuthenticationFailed("缺少token")
        #判断token值是否对应用户
        user_obj = Author.objects.filter(token=token).first()
        if not user_obj:
            raise AuthenticationFailed("无效的token")
        return user_obj,token
View Code

去视图里给BookView添加认证,注册

from .models import Book
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import Book,Author
from app01.serializer import BookSerializer
from .authentication import MyAuth

import uuid

class BookView(APIView):

    authentication_classes = [MyAuth,]  #认证

    def get(self,request):
        #查看所有的图书
        queryset = Book.objects.all()
        ser_obj = BookSerializer(queryset,many=True)#转序列化
        return Response(ser_obj.data)#序列化后的数据

    def post(self,request):
        #新增图书
        ser_obj = BookSerializer(data=request.data)
        if ser_obj.is_valid():  #如果通过校验
            ser_obj.save()
            return Response(ser_obj.validated_data)

class BookEditView(APIView):
    #查看单条数据
    def get(self,request,pk):
        book_obj = Book.objects.filter(id=pk).first()
        ser_obj = BookSerializer(book_obj)  #转序列化
        return Response(ser_obj.data)  #序列化后的数据
    #更新数据
    def put(self,request,pk):
        book_obj = Book.objects.filter(id=pk).first()
        #instance=book_obj原来的数据,data=request.data新的数据,partial=True允许部分更新
        ser_obj = BookSerializer(instance=book_obj,data=request.data,partial=True)
        if ser_obj.is_valid():  #检验成功
            ser_obj.save()
            return Response(ser_obj.validated_data)#通过校验的数据
        else:
            return Response(ser_obj.errors)  #返回错误信息

    #删除
    def delete(self,request,pk):
        book_obj = Book.objects.filter(id=pk).first()
        if not book_obj:
            return Response({"code":1001,"error":"删除的数据不存在"})  #code返回的状态码
        else:
            book_obj.delete()
            return Response("")


#登录
class LoginView(APIView):
    def post(self,request):
        #获取前端传过来的用户名和密码
        username = request.data.get("username","")
        pwd = request.data.get("pwd","")
        #验证用户登录是否成功
        user_obj = Author.objects.filter(name=username,pwd=pwd).first()
        if not user_obj:
            return Response("用户名或密码不正确")
        token = uuid.uuid4()
        user_obj.token = token
        user_obj.save()
        return Response(token)
View Code

启动:127.0.0.1:8000/login,然后在POST体检请求里输入{"username":"admin456","pwd":"admin456"}当做前端传来的用户名密码,做检验,然后表里会自动生成token值

验证token值是否有效:http://127.0.0.1:8000/books?token=812b88fc5e05438cb84cbd28a41a6f67

验证用户名密码是否正确:直接输入错误的用户名或者密码,在POST提交的请求里{"username":"admin456","pwd":"admin456"}

 

ContentType组件

models.py创建表

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation

# Create your models here.

class Food(models.Model):
    """
    id   title
    1    桃李面包
    2    山东大馒头
    """
    title = models.CharField(max_length=32)
    # 适用于反向查询不生成字段
    coupons = GenericRelation(to="Coupon")


class Fruit(models.Model):
    """
    id    title
    1     泰国金枕
    2     贵妃芒
    """
    title = models.CharField(max_length=32)


class Coupon(models.Model):
    """
    id    title              food_id   fruit_id
    1     山东大馒头买一送一   2            null
    2     买芒果送贵妃         null      2

    id   title                MyTable_id   object_id
    1    山东大馒头买一送一     1           2
    2     买芒果送贵妃          2          2
    """
    title = models.CharField(max_length=32)
    # 第一版 多张外键关系
    # food_obj = models.ForeignKey(to="Food", null=True, blank=True)
    # fruit_obj = models.ForeignKey(to="Fruit", null=True, blank=True)
    # 第二版 我们自己解决
    # MyTable = models.ForeignKey(to="MyTable")
    # object = models.IntegerField()
    # 第三版 django ContentType
    # 第一步 跟ContentType表创建外键关系
    content_type = models.ForeignKey(to=ContentType)   #找表
    # 第二步 声明object_id
    object_id = models.IntegerField()   #找字段山东大馒头
    # 第三步 让content_type, object_id关联
    content_obj = GenericForeignKey("content_type", "object_id")



# Django 给我们提供了这样一张表
# class MyTable(models.Model):
#     """
#     id  appname  tablename
#     1   app02     Food
#     2   app02     Fruit
#     """
#     # 放app的名字
#     app_name = models.CharField(max_length=32)
#     # 表名字
#     table_name = models.CharField(max_length=32)
View Code

urls.py

from django.conf.urls import url
from django.contrib import admin
from app01.views import BookView, BookEditView, LoginView, TestView

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    
    url(r'^test', TestView.as_view()),
   
]
View Code

views.py

from app02.models import Coupon, Food
class TestView(APIView):
    def get(self, request):
        # 给山东大馒头加优惠券
        food_obj = Food.objects.filter(id=1).first()
        Coupon.objects.create(title="买一赠一", content_obj=food_obj)
        # 查看山东大馒头有哪些优惠券
        for coupon in food_obj.coupons.all():
            print(coupon.title)
        # 查看优惠券绑定的商品
        coupon_obj = Coupon.objects.first()
        print(coupon_obj.content_obj.title)

        return Response("ok")
View Code

数据查看右侧的表

posted on 2018-11-08 19:30  liangliang123456  阅读(158)  评论(0)    收藏  举报

导航