继承代码阅读与注释

一、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'])
    #将创建的代码全部写入文件中

posted @ 2020-04-08 22:15  ITAS2024  阅读(239)  评论(0编辑  收藏  举报