• 继承代码阅读与注释


    一、Django部分(Journal / User)

    • journal(仅以下提到的py文件有用,其他都不用管)

      • models.py + serializers.py: (模型+序列化方法,序列化产生json

        • 用户IP记录 UserIp(ip=char,count=int) 对应序列化,id,ip,count
        • 访问数 VisitCount (count=int) 对应序列化,id,count
        • 日期记录 DayCount(day=date,count=int) 对应序列化,id,date,coun
      • urls.py

        • 访问localhost:8000/api/journal/visit/ 调用views.Visit
        • 访问localhost:8000/api/journal/statistics/ 调用views.Statistics
      • views.py

        • Visit

          只有一个POST方法,
          
          
          count 置为 VisitCount对象的数量
          #这句没用到,不知道为什么在这,对应代码如下,后续一致,不再赘述。
          count = VisitCount.objects.all()
          
          
          根据request.META获取HTTP报文的IP,若同一IP则该UserIp的count+1,
          否则新建一个UserIp,其count赋值为1
          
           if 'HTTP_X_FORWARDED_FOR' in request.META:
                      client_ip = request.META['HTTP_X_FORWARDED_FOR']
                      client_ip = client_ip.split(",")[0]
                  else:
                      client_ip = request.META['REMOTE_ADDR']
          
                  exist = UserIp.objects.filter(ip=str(client_ip))
                  if exist:
                      uip = exist[0]
                      uip.count += 1
                  else:
                      uip = UserIp()
                      uip.ip = client_ip
                      uip.count = 1
                  uip.save()
          
          根据当前日期找出对应的日期记录,找到则对应count+1,否则新建一个DayCount对象,date置为现在的时间,count记为1
          
           date = timezone.now().date()
                  today = DayCount.objects.filter(day=date)
                  if today:
                      day_record = today[0]
                      day_record.count += 1
                  else:
                      day_record = DayCount()
                      day_record.dayTime = date
                      day_record.count = 1
                  day_record.save()
          
          返回HTTP201(成功)
          
        • Statistics

          只有一个Get方法,
          data = {
          "visit_count": vist_count['count__sum'],  #返回各IP访问量之和
          "date_count_list": date_count_list_serializer.data, #所有DayCount的json
          "network_api_count": network_api_count, #网络数目
          "user_count":user_count #用户数目
          }
          #实际数据例子如下
          {
              "visit_count": 12,
              "date_count_list": [
                  {
                      "id": 1,
                      "day": "2020-04-06",
                      "count": 12
                  }
              ],
              "network_api_count": 1,
              "user_count": 2
          }
          
    • user

      • models.py + serializers.py:

      • test.py

        一组用户注册测试数据,python manage.py test user/ 可自动化测试。

      • urls.py

        urlpatterns = [
            url(r'^register/$', views.UserRegister.as_view()),
            url(r'^login/$',obtain_jwt_token),
            url(r'^info/$',views.UserInfo.as_view())
        ]
        分别是
        访问localhost:8000/api/user/register/  调用views.UserRegistor
        访问localhost:8000/api/user/login/  调用obtain_jwt_token,验证相关,他们掉包做好了,其实可以不用管这部分
        访问localhost:8000/api/user/ingo/  调用views.UserInfo
        
      • utils.py

        用户认证相关的设置,也可以不管

      • views.py

        • UserRegistor

          只有一个POST方法,用于新建用户
           def post(self, request):
                  serializer = UserSerializer(data=request.data)#json->对象
                  if serializer.is_valid():#数据有效则建立
                      serializer.save()#保存用户对象
                      # 注册时签发一个token来自动登录
                      payload = jwt_payload_handler(serializer.instance)
                      token = jwt_encode_handler(payload)
                      res = serializer.data
                      res["token"] = token
                      return Response(res, status=status.HTTP_201_CREATED)
                  return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)#无效则返回HTTP400
          
        • UserInfo

          只有Get方法,
          返回用户数据Json
          例子如下
          {
              "id": 1,
              "password": "pbkdf2_sha256$120000$gCiyqC4gkN1k$/IVeCbd5gsu2T5RMNRpO50MxeC9vx14diuKXgSGDx9A=",
              "username": "pandapan",
              "email": "1009303269@qq.com",
              "is_active": true,
              "is_staff": true
          }
          

    二、前端部分

    关键前端代码注释

    三、后端部分

    permission.py,定义的是用户对于模型操作的权限:

    from NeuralNetwork.models import Network
    
    class ChangeModel(object):
    
    
    
    def has_permission(self, request,view):
        aquire_object = Network.objects.get(pk=view.kwargs['pk'])
        if request.method == 'GET' or request.user.id == aquire_object.creator_id:
            return True
        else:
            return False
        #如果Network所有者和请求访问者id相同或者为get请求,返回true,否则为false
    
    
    

    model.py:

    class Network(models.Model):
    
    creator = models.ForeignKey('user.User',on_delete=models.CASCADE,null=True)
    structure = models.TextField()
    name = models.TextField(null=True)
    time = models.DateTimeField(auto_now=True)
    

    network共有4个属性,创建者ID,模型名称,创建时间和structure。其中struture为json型文本,记录了network的完整结构。

    serializers.py,将network序列化,比较常规

    views.py,重要文件,定义了一系列的交互操作

    class NetworkList(APIView):
        permission_classes = (permissions.IsAuthenticated,)
    #允许身份验证通过的用户访问
    ```
    def get(self, request):
        user_id = request.GET['id']
        if user_id is None:
            return Response("need user id", status=status.HTTP_400_NOT_FOUND)
        network_list = Network.objects.filter(creator=user_id).values('id', 'time', 'creator_id', 'name')
        return Response(list(network_list), status=status.HTTP_200_OK)
    #返回登录用户创建的所有Network信息表,不包括structure结构,而是一张统计表
    
    def post(self, request):
    
        creator = request.user.id
        data = {
            "name": request.data["name"],
            "creator": creator,
            "structure": json.dumps(request.data["structure"])
        }
        serializer = NetworkSerializer(data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    ```
    #储存用户所创建的Network
    class NetworkDetail(APIView):
        permission_classes = (ChangeModel,)
    #在permission.py中定义,要求用户ID与network ID相同
    ```
    def get_object(self, pk):
        try:
            return Network.objects.get(pk=pk)
        except Network.DoesNotExist:
            raise Http404
    #获取ID为pk的Network
    def get(self, request, pk):
        net = self.get_object(pk)
        serializer = NetworkSerializer(net)
        return Response(serializer.data)
    #获取ID为pk的Network,并将其序列化,返回给用户
    def put(self, request, pk):
        net = self.get_object(pk)
        data = {
            "name": request.data["name"],
            "structure": json.dumps(request.data["structure"])
        }
        serializer = NetworkSerializer(net, data=data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
    #更新id=pk的network
    def delete(self, request, pk):
        net = self.get_object(pk)
        net.delete()
        return Response(status=status.HTTP_200_OK)
    #删除id为pk的Network
    ```
    
    @api_view(['POST'])
    def gen_code(request):
        result = {}
        try:
            result["Main"], result["Model"], result["Ops"] = ops.main_func(request.data)
            #调用translate/ops.py中的main_func生成完整代码,并返回给客户端
        except Exception as e:
            return Response({str(e)}, status=status.HTTP_400_BAD_REQUEST)
        else:
            return Response(result, status=status.HTTP_200_OK)
    
    #todo:虽然看起来没啥问题但是问题绝对很大,两个请求同时处理绝对会挂掉!!!!!!!
    @api_view(['POST'])
    def download_project(request):
        data = request.data
        write_file(data)
        zipf = zipfile.ZipFile("project_VisualPytorch.zip", 'w',zipfile.ZIP_DEFLATED)
        #创建一个压缩文件对象
        pre_len = len(settings.FILE_DIR)
        for parent, dirnames, filenames in os.walk(settings.FILE_DIR):
            for filename in filenames:
                pathfile = os.path.join(parent, filename)
                arcname = pathfile[pre_len:].strip(os.path.sep)  # 相对路径
                zipf.write(pathfile, arcname)
        zipf.close()
        #将setting.FILE_DIR(规定的生成文件文件夹)所有的文件添加到压缩包内
    ```
    response = StreamingHttpResponse(file_iterator("project_VisualPytorch.zip"))
    response['Content-Type'] = 'application/zip'
    response['Content-Disposition'] = 'attachment;filename="project_VisualPytorch.zip"'
    #将生成的压缩文件发送给用户,需要注意到的是使用了file_iterator将zip文件变成了字节流传送,原理不明。但直接沿用应该没问题。
    return response
    ```
    
    def file_iterator(file_name, chunk_size=512):
        with open(file_name, 'rb') as f:
            while True:
                c = f.read(chunk_size)
                if c:
                    yield c
                else:
                    break
    
    def write_file(data):
        if os.path.exists(os.path.join(settings.FILE_DIR,"project/Main.py")):
            os.remove(os.path.join(settings.FILE_DIR,"project/Main.py"))
        if os.path.exists(os.path.join(settings.FILE_DIR,"project/Model.py")):
            os.remove(os.path.join(settings.FILE_DIR,"project/Model.py"))
        if os.path.exists(os.path.join(settings.FILE_DIR,"project/Ops.py")):
            os.remove(os.path.join(settings.FILE_DIR,"project/Ops.py"))
        if os.path.exists("project_VisualPytorch.zip"):
            os.remove("project_VisualPytorch.zip")
            #服务器在创建前先删除之前创建的全部相关文件
        root_dir = os.path.join(settings.FILE_DIR, "project")
        file_main = open(os.path.join(root_dir, "Main.py"), "w")
        file_model = open(os.path.join(root_dir, "Model.py"), "w")
        file_ops = open(os.path.join(root_dir, "Ops.py"), "w")
        file_main.write(data['main'])
        file_model.write(data['model'])
        file_ops.write(data['ops'])
        #将创建的代码全部写入文件中
    

  • 相关阅读:
    jstack 分析程序性能
    网关-zuul介绍 第一篇 网关解决的问题
    通过Fegin远程调用 ,返回JPA Page 对象报错
    css自定义字体
    CSS3选择器
    表格操作
    商品筛选条件
    多级菜单
    一排元素往下掉
    控制提示框不溢出父级盒子
  • 原文地址:https://www.cnblogs.com/NAG2020/p/12663288.html
Copyright © 2020-2023  润新知