python项目_Django注意点

登录后进入欢迎页

from django.contrib.auth.decorators import login_required, permission_required
@login_required(login_url="/myauth/login/") #在使用welcome 处理前,先查看用户是否登录,if not,跳转到login_url处理,登录成功后,继续跳转到welcome页面
def welcome(request):
    return render(request,'welcome.html')

更新数据

@permission_required(perm="myapp.change_student",login_url="/myauth/login/")
def update_student(request):
    return render(request,'student_permission.html')
    

登录

def login_view(request):
	# request.session  #一个既可读又可写的类似于字典的对象,表示当前的会话
	# login()是向django_session 表中添加记录,代表当前用户的会话
    if request.method == "GET":
        return render(request,'userlogin.html')
    else:
        logname = request.POST.get("logname")
        logpwd = request.POST.get("logpwd")
        user = authenticate(username=logname,password=logpwd)   # 认证用户,该方法不检查is_active标志位
        print("authenticate()的结果:user=",user)
        if user is not None:
            if user.is_active:
                login(request,user)   # login向session中添加SESSION_KEY, 便于对用户进行跟踪
                request.session["uname"] = logname  # 手工向Session中设置登录名
                return redirect(reverse("myauth:welcome"))

        return redirect(reverse("myauth:login"))

django_session表
在这里插入图片描述

中间件

from django.shortcuts import redirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin

REQUIRED_LOGIN = ['/fruit/buy/','/fruit/cart/']

class LoginMiddleware(MiddlewareMixin):

    def process_request(self,request):
        path = request.path    # 获取当前请求路径
        print("当前请求路径:",path)
        if path in REQUIRED_LOGIN:
            if not request.session.get("uname"):  #检查session 确定用户在请求当前页面是否有登录
                return redirect(reverse("home:login"))

自定义权限

    class Meta:
        verbose_name = "电影模型"
        verbose_name_plural = verbose_name
        permissions = (  # 在auth_permission 表中添加以下两个权限,可以通过django 后台管理系统 or 代码修改某个用户的权限
            ("vip","vip can do"),
            ("ordinary","ordinary can do")
        )       

    {% if perms.homeworkapp.ordinary %} <!-- 调用方法为perms.projectname.permissionname-->
        <ul>
            {% for movie in movies %}
               <li> {{ movie.name }} </li>
            {% endfor %}
        </ul>
    {% endif %}

自定义表格

<form action="{% url 'formapp:reg' %}" method="post">
        {% csrf_token %}
        {{ regform.as_p }} <!-- {{ formname.as_p }} 将表单的每个输入框包裹在一个<p>标签内 tags-->
        <input type="submit" value="注册"/>
    </form>

自定义某模型类的序列化对象

  • 在某应用的根目录下创建serializers.py
from rest_framework import serializers
from restapp.models import Student

# 自定义学生序列化类
class StudentSerializers(serializers.ModelSerializer):
    class Meta:
        model = Student   # 关联学生模型
        # fields = "__all__"  # 序列化学生模型的所有类属性
        fields = (
            "name",
            "age",
            "sex",
            "score",
        )
  • 子路由
from django.urls import path

from restapp.views.student_class_view import StudentView

from restapp.views.student_func_view import student_view

urlpatterns = [
    path('students/',StudentView.as_view()),  # as_view()
    path('student/<sid>/',student_view),
]
  • 在views文件夹中

student_class_view

from rest_framework import status
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response
from rest_framework.views import APIView

from restapp.models import Student
from restapp.serializers import StudentSerializers

#  基于类的视图
class StudentView(APIView):

    def get(self,request):
        students = Student.objects.all()
        pg = PageNumberPagination()  # 实例化Rest framework中的分页器对象
		# 获取分页数据,参数一 分页的数据,QuerySet类型,请求request,分页的视图,self代表自己
		# 此处不理解的是 分页的数据是所有学生, view是自己是啥意思???
        page = pg.paginate_queryset(queryset=students,request=request,view=self)
        
        
        # 为了能够序列化一个查询集或者一个对象列表  而不是一个单独的对象,需要在实例化序列化器类的时候传一个many=True参数。这样就能序列化一个查询集或一个对象列表。
        sers = StudentSerializers(instance=page,many=True)   # 将所有学生对象序列化,对分完页码的数据进行序列化
        return Response(sers.data,status=status.HTTP_200_OK)

    def post(self,request):  # 添加新数据
        sers = StudentSerializers(data=request.data)   # 将POST请求数据封装到序列化对象中
        if sers.is_valid():    # 验证数据是否有效
            sers.save()   # 保存
            return Response(sers.data,status=status.HTTP_201_CREATED)

        return Response(status=status.HTTP_400_BAD_REQUEST)

student_func_view

from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response

from restapp.models import Student
from restapp.serializers import StudentSerializers


@api_view(["GET","PUT","DELETE","PATCH"])
def student_view(request,sid):
    try:
        student = Student.objects.get(pk=sid)
    except Student.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        sers = StudentSerializers(instance=student)
        return Response(sers.data,status=status.HTTP_200_OK)
    elif request.method == "PUT":  # 添加新数据
        sers = StudentSerializers(instance=student,data=request.data)  # 使用提交的新数据覆盖查询的旧数据
        if sers.is_valid():
            sers.save()   # 更新
            return Response(sers.data)

        return Response(status=status.HTTP_400_BAD_REQUEST)

    elif request.method == "PATCH":
        # 默认情况下,序列化器必须传递所有必填字段的值,否则就会引发验证错误。但是我们可以将 partial参数指定为True,来允许部分更新,而不至于产生错误
        # instance 为从数据库中查询到模型类
        # data 为从用户发来的请求数据的字典类
        sers = StudentSerializers(instance=student, data=request.data,partial=True)  # 使用提交的新数据覆盖查询的旧数据
        if sers.is_valid():
            sers.save()  # 更新
            return Response(sers.data)

        return Response(status=status.HTTP_400_BAD_REQUEST)

    elif request.method == "DELETE":
        student.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


URL分发器是如何定位到应该交给那个视图函数处理呢?

不懂为啥,请参考:
python_装饰器入门教程哦

url_view_map = {}


def route(path_url_map):
    def inner(func):
        def second_dec(*args, **kwargs):
            url_view_map[path_url_map['path']] = func
            func(*args,**kwargs)
        return second_dec
    return inner


@route({'path': r'/index'})  # 自定义url,并且将'/index' 和index视图函数关联起来
def index(request):
    print(request)
    pass

index(123)
url_view_map = {}


def route(path_url_map):
    def inner(func, request):
        url_view_map[path_url_map['path']] = func
        func(request)

    return inner


@route({'path': r'/index'})  # 自定义url,并且将'/index' 和index视图函数关联起来
def index(request):
    print(request)
    pass


# index(index('123'), '123')
# index('123') #此处inner函数还需要func,虽然此处同时传入参数
# 目前不知道为啥  # 猜测是函数及其形式参数无法同屏出现,我明明传入request,到底被谁吞了?
# 程序会不会无法识别一个index 调用和index 函数对象?
# TypeError: inner() missing 1 required positional argument: 'request'

# 测试2
我把index()设置成无参的函数,显示TypeError: 'NoneType' object is not callable

问题 向上指

参考文献

Django中的as_view方法源码分析

猜你喜欢

转载自blog.csdn.net/sinat_40701582/article/details/105723607
今日推荐