Django学习笔记-VS Code本地运行项目

news2024/12/22 20:52:34

截止到上一章节:Django 学习笔记-Web 端授权 AcWing 一键登录,我们的项目一直是部署在云服务器上,包括编写代码以及调试运行也是在云服务器上,现在我们尝试将其放回本地运行。

CONTENTS

    • 1. 将项目传到本地
    • 2. 虚拟环境配置
    • 3. 修改项目相关文件

1. 将项目传到本地

这一步可以使用 Git 也可以使用 SCP,由于之前项目上传在 AcGit 上,只能在 AC Terminal 中拉取,因此使用 SCP 远程传输:

scp -r -P 20000 asanosaki@<公网IP>:djangoapp .  # 在要存放项目的目录执行该指令

2. 虚拟环境配置

我们需要先配置一个和云服务上相同的虚拟环境,首先在 VS Code 中打开该项目并且打开终端,在项目根目录下创建虚拟环境:

python -m venv venv

虚拟环境创建成功之后,一般不会自动启用,所以需要启用它,进入 env/Scripts 目录运行脚本 Activate.ps1

cd .\venv\Scripts\
.\Activate.ps1

此时可以看到命令行首部多了 (venv),说明已进入虚拟环境,然后选择解释器即可:

在这里插入图片描述

现在我们安装所需的环境:

pip install django

3. 修改项目相关文件

首先修改一下我们的打包脚本 compress_game_js.sh

#! /bin/bash

JS_PATH=../game/static/js/
JS_PATH_DIST=${JS_PATH}dist/
JS_PATH_SRC=${JS_PATH}src/

find ${JS_PATH_SRC} -type f -name '*.js' | sort | xargs cat > ${JS_PATH_DIST}game.js

然后打开 Git Bash,进入 scripts 文件夹即可运行脚本:

sh compress_game_js.sh

然后将 djangoapp/settings.py 中的 Redis 配置删除,即删除以下这段话:

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
        },
    },
}
USER_AGENTS_CACHE = 'default'

同样在该文件中需要将 localhost 添加到 ALLOWED_HOSTS 中:

ALLOWED_HOSTS = ["8.130.54.44", "app4007.acapp.acwing.com.cn", "localhost"]

然后将 AcWing 一键授权登录的相关文件夹删除:game/views/settings/acwinggame/urls/settings/acwing,然后修改 urls/settings/index.py 中的路由:

from django.urls import path
from game.views.settings.getinfo import getinfo
from game.views.settings.login import mylogin
from game.views.settings.logout import mylogout
from game.views.settings.register import register

urlpatterns = [
    path('getinfo/', getinfo, name='settings_getinfo'),
    path('login/', mylogin, name='settings_login'),
    path('logout/', mylogout, name='settings_logout'),
    path('register/', register, name='settings_register'),
]

修改 AcGame 类,去掉 AcWingOS API,且改为非模块化引入 JS 方式,即去掉 export 关键字:

class AcGame {
    constructor(id) {
        this.id = id;
        this.$ac_game = $('#' + id);  // jQuery通过id找对象的方式

        this.settings = new Settings(this);
        this.menu = new AcGameMenu(this);
        this.playground = new AcGamePlayground(this);

        this.start();
    }

    start() {
    }
}

同时前端的 web.html 文件也需要修改:

{% load static %}

<head>
    <link rel="stylesheet" href="{% static 'css/jquery-ui.min.css' %}">
    <script src="{% static 'js/jquery-3.6.1.min.js' %}"></script>
    <link rel="stylesheet" href="{% static 'css/game.css' %}">
    <script src="{% static 'js/dist/game.js' %}"></script>
</head>

<body style="margin: 0">
    <div id="ac_game_1"></div>
    <script>
        $(document).ready(function() {
            let ac_game = new AcGame("ac_game_1");
        });
    </script>
</body>

最后修改 Settings 类,去掉 AcWing 一键登录功能,且修改 ajax 请求的地址:

class Settings {
    constructor(root) {
        this.root = root;
        this.platform = 'WEB';  // 默认为Web前端
        this.username = '';  // 初始用户信息为空
        this.avatar = '';

        this.$settings = $(`
            <div class='ac_game_settings'>
                <div class='ac_game_settings_login'>
                    <div class='ac_game_settings_title'>
                        Login
                    </div>
                    <div class='ac_game_settings_username'>
                        <div class='ac_game_settings_item'>
                            <input type='text' placeholder='Username'>
                        </div>
                    </div>
                    <div class='ac_game_settings_password'>
                        <div class='ac_game_settings_item'>
                            <input type='password' placeholder='Password'>
                        </div>
                    </div>
                    <div class='ac_game_settings_submit'>
                        <div class='ac_game_settings_item'>
                            <button>Login</button>
                        </div>
                    </div>
                    <div class='ac_game_settings_errormessage'>
                    </div>
                    <div class='ac_game_settings_option'>
                        Register
                    </div>
                </div>
                <div class='ac_game_settings_register'>
                    <div class='ac_game_settings_title'>
                        Register
                    </div>
                    <div class='ac_game_settings_username'>
                        <div class='ac_game_settings_item'>
                            <input type='text' placeholder='Username'>
                        </div>
                    </div>
                    <div class='ac_game_settings_password ac_game_settings_password_first'>
                        <div class='ac_game_settings_item'>
                            <input type='password' placeholder='Password'>
                        </div>
                    </div>
                    <div class='ac_game_settings_password ac_game_settings_password_second'>
                        <div class='ac_game_settings_item'>
                            <input type='password' placeholder='Confirm Password'>
                        </div>
                    </div>
                    <div class='ac_game_settings_submit'>
                        <div class='ac_game_settings_item'>
                            <button>Register</button>
                        </div>
                    </div>
                    <div class='ac_game_settings_errormessage'>
                    </div>
                    <div class='ac_game_settings_option'>
                        Login
                    </div>
                </div>
            </div>
        `);

        this.$login = this.$settings.find('.ac_game_settings_login');
        this.$login_username = this.$login.find('.ac_game_settings_username input');
        this.$login_password = this.$login.find('.ac_game_settings_password input');
        this.$login_submit = this.$login.find('.ac_game_settings_submit button');
        this.$login_errormessage = this.$login.find('.ac_game_settings_errormessage');
        this.$login_register = this.$login.find('.ac_game_settings_option');
        this.$login.hide();

        this.$register = this.$settings.find('.ac_game_settings_register');
        this.$register_username = this.$register.find('.ac_game_settings_username input');
        this.$register_password = this.$register.find('.ac_game_settings_password_first input');
        this.$register_confirm_password = this.$register.find('.ac_game_settings_password_second input');
        this.$register_submit = this.$register.find('.ac_game_settings_submit button');
        this.$register_errormessage = this.$register.find('.ac_game_settings_errormessage');
        this.$register_login = this.$register.find('.ac_game_settings_option')
        this.$register.hide();

        this.root.$ac_game.append(this.$settings);

        this.start();
    }

    start() {  // 在初始化时需要从服务器端获取用户信息
        this.getinfo();
        this.add_listening_events();
    }

    add_listening_events() {  // 绑定监听函数
        this.add_listening_events_login();
        this.add_listening_events_register();
    }

    add_listening_events_login() {
        let outer = this;
        this.$login_register.click(function() {
            outer.register();
        });
        this.$login_submit.click(function() {
            outer.login_on_remote();
        });
    }

    add_listening_events_register() {
        let outer = this;
        this.$register_login.click(function() {
            outer.login();
        });
        this.$register_submit.click(function() {
            outer.register_on_remote();
        });
    }

    login_on_remote() {  // 在远程服务器上登录
        let outer = this;
        let username = this.$login_username.val();
        let password = this.$login_password.val();
        this.$login_errormessage.empty();  // 先清空报错信息

        $.ajax({
            url: 'http://localhost:8000/settings/login/',
            type: 'GET',
            data: {
                username: username,
                password: password,
            },
            success: function(resp) {
                console.log(resp);
                if (resp.result === 'success') {  // 登录成功
                    location.reload();  // 刷新页面
                } else {  // 登录失败
                    outer.$login_errormessage.html(resp.result);  // 显示报错信息
                }
            }
        });
    }

    register_on_remote() {  // 在远程服务器上注册
        let outer = this;
        let username = this.$register_username.val();
        let password = this.$register_password.val();
        let confirm_password = this.$register_confirm_password.val();
        this.$register_errormessage.empty();

        $.ajax({
            url: 'http://localhost:8000/settings/register/',
            type: 'GET',
            data: {
                username: username,
                password: password,
                confirm_password: confirm_password,
            },
            success: function(resp) {
                console.log(resp);
                if (resp.result === 'success') {
                    location.reload();
                } else {
                    outer.$register_errormessage.html(resp.result);
                }
            }
        });
    }

    logout_on_remote() {  // 在远程服务器上登出
        if (this.platform === 'ACAPP') return false;  // AcApp应该是直接关闭窗口退出

        $.ajax({
            url: 'http://localhost:8000/settings/logout/',
            type: 'GET',
            success: function(resp) {
                console.log(resp);
                if (resp.result === 'success') {
                    location.reload();
                }
            }
        });
    }

    register() {  // 打开注册界面
        this.$login.hide();
        this.$register.show();
    }

    login() {  // 打开登录界面
        this.$register.hide();
        this.$login.show();
    }

    getinfo() {
        let outer = this;
        $.ajax({
            url: 'http://localhost:8000/settings/getinfo/',
            type: 'GET',
            data: {
                platform: outer.platform,
            },
            success: function(resp) {  // 调用成功的回调函数,返回的Json字典会传给resp
                console.log(resp);  // 控制台输出查看结果
                if (resp.result === 'success') {
                    outer.username = resp.username;
                    outer.avatar = resp.avatar;
                    outer.hide();
                    outer.root.menu.show();
                } else {  // 如果未登录则需要弹出登录界面
                    outer.login();
                }
            }
        });
    }

    hide() {
        this.$settings.hide();
    }

    show() {
        this.$settings.show();
    }
}

顺带还需要修改一下 game.css

.ac_game_menu {
    width: 100%;
    height: 100%;
    background-image: url('/static/image/menu/background2.jpeg');  /* 注意不用带公网IP */
    background-size: 100% 100%;
    user-select: none;
}

.ac_game_menu_btgroup {
    width: 20vw;
    position: relative;
    top: 30%;
    left: 20%;
}

.ac_game_menu_btgroup_bt {
    height: 7vh;
    width: 15vw;
    color: white;
    font-size: 3vh;
    line-height: 7vh;
    font-style: italic;
    cursor: pointer;
    text-align: center;
    background-color: rgba(39, 21, 28, 0.6);
    border-radius: 10px;
    letter-spacing: 0.5vw;
}

.ac_game_menu_btgroup_bt:hover {
    transform: scale(1.2);
    transition: 100ms;
}

.ac_game_playground {
    height: 100%;
    width: 100%;
    user-select: none;
}

.ac_game_settings {
    width: 100%;
    height: 100%;
    background-image: url('/static/image/menu/background2.jpeg');
    background-size: 100% 100%;
    user-select: none;
}

.ac_game_settings_login {
    height: 32vh;
    width: 20vw;
    position: relative;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: rgba(0, 0, 0, 0.7);
    border-radius: 5px;
}

.ac_game_settings_register {
    height: 39vh;
    width: 20vw;
    position: relative;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: rgba(0, 0, 0, 0.7);
    border-radius: 5px;
}

.ac_game_settings_title {
    color: white;
    font-size: 3.5vh;
    text-align: center;
    height: 7vh;
    line-height: 7vh;
}

.ac_game_settings_username {
    display: block;
    height: 7vh;
}

.ac_game_settings_password {
    display: block;
    height: 7vh;
}

.ac_game_settings_submit {
    display: block;
    height: 7vh;
}

.ac_game_settings_errormessage {
    color: red;
    font-size: 1.5vh;
    display: inline;
    float: left;
    padding-left: 1vw;
}

.ac_game_settings_option {
    color: white;
    font-size: 1.5vh;
    display: inline;
    float: right;
    padding-right: 1vw;
    cursor: pointer;
}

.ac_game_settings_item {
    width: 100%;
    height: 100%;
}

.ac_game_settings_item > input {
    width: 90%;
    line-height: 3vh;
    position: relative;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.ac_game_settings_item > button {
    color: black;
    width: 30%;
    line-height: 3vh;
    font-size: 2vh;
    position: relative;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: rgb(199, 237, 204);
    border-radius: 7px;
    cursor: pointer;
}

最后我们将 .git 文件夹删除,重新上传至 Github(先创建一个仓库 Small_Ball_Fight):

git init
git remote add origin git@github.com:AsanoSaki/Small_Ball_Fight.git
git add .
git commit -m "create small ball fight"
git push --set-upstream origin master

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/702444.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何录音转文字?这份录音转文字教程你必须知道

在现代快节奏的工作环境中&#xff0c;电脑会议录音转文字成为了一项非常重要的任务。但是很多人不知道电脑会议录音转文字怎么转&#xff1f;如果你也正有这样的疑问&#xff0c;那么你就来对地方了&#xff01;在本篇文章中&#xff0c;我们将为你介绍几款备受推崇的录音转文…

联想校招雇品年轻化:硬科技「校招+雇品」的创新打法

联想计划3年内增加12,000名研发人才&#xff0c;并明确20%的New Hire将来自校园招聘。 人才梯队的构成预示着企业未来的发展方向与加速度。联想对年轻人才关注与吸引从未放慢脚步&#xff0c;始终相信年轻即代表未来。更多年轻科技人才加入&#xff0c;会为企业注入创新活力&a…

LeetCode 75 —— 62. 不同路径

LeetCode 75 —— 62. 不同路径 一、题目描述&#xff1a; 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &…

Appium之xpath定位详解

目录 一、基础定位 二、contains模糊定位 三、组合定位 四、层级定位 前面也说过appium也是以webdriver为基的&#xff0c;对于元素的定位也基本一致&#xff0c;只是增加一些更适合移动平台的独特方式&#xff0c;下面将着重介绍xpath方法&#xff0c;这应该是UI层元素定位…

前端系列20集-vue3,微信小程序,brew,redis,WebSocket

onShow() {uni.checkSession({success: (data) > {this.getSessionId()},fail: () > {this.getSessionId()}}) }, // 获取用户的手机号 getPhoneNumber(info) {let wxAuth {encryptedData: info.detail.encryptedData,iv: info.detail.iv,sessionId: uni.getStorageSync…

Java反射源码学习之旅 | 京东云技术团队

1 背景 前段时间组内针对“拷贝实例属性是应该用BeanUtils.copyProperties&#xff08;&#xff09;还是MapStruct”这个问题进行了一次激烈的battle。支持MapStruct的同学给出了他嫌弃BeanUtils的理由&#xff1a;因为用了反射&#xff0c;所以慢。 这个理由一下子拉回了我遥…

青岛农商与中电金信鲸Bot RPA的一次紧密合作

260%、350%、313%、400%、1200%&#xff0c;这些都是青岛农商银行近期通过鲸Bot RPA跑出来的各个业务流程的ROI&#xff0c;原来选择合适的RPA真的这么有用&#xff01;青岛农商还亲切地给RPA起了一个昵称&#xff1a;小鑫&#xff0c;从此小鑫就是青岛农商第一位正式的数智员工…

群晖安装、卸载、停用套件

安装套件 点击套件中心 点击所有套件&#xff0c;选中需要安装的套件&#xff0c;店家安装套件&#xff0c;或者试用&#xff0c;等待安装完成即可 卸载套件 点击已安装 点击图标或者文字&#xff0c;注意&#xff1a;不要点打开 点击向下的箭头 点击停用&#xff0c;或者卸载…

puppeteer实现文件下载

puppeteer实现文件下载 puppeteer版本&#xff1a; "puppeteer": "^20.7.3",脚本需要的其他依赖 const axios require(axios); const FormData require(form-data); const fs require(fs);本脚本测试数据网站&#xff1a;https://unsplash.com/photo…

基于Java民宿管理系统设计实现(源码+lw+部署文档+讲解等)

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

【机器学习】数据预处理 - 归一化和标准化

「作者主页」&#xff1a;士别三日wyx 「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 数据预处理 一、数据预处理API二、准备数据集三、归…

没有u盘,怎么将电脑上的便签文件拷贝到手机上?

在如今数字化的时代&#xff0c;便签软件已经成为我们工作和生活中很重要的一部分&#xff0c;在便签中我们会记录很多重要事项或者重要文件。有时候&#xff0c;我们可能会遇到这样的问题&#xff1a;当我们在电脑便签上保存了一些重要文件&#xff0c;想要将文件拷贝到手机上…

【Redis常见命令】 —— 关于Redis的一点儿知识

&#x1f4a7; 【 R e d i s 常见命令】——关于 R e d i s 的一点儿知识 \color{#FF1493}{【Redis常见命令】 —— 关于Redis的一点儿知识} 【Redis常见命令】——关于Redis的一点儿知识&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f…

Java框架学习(二)SSM体系:Spring、SpringMVC、MybatisPlus

文章目录 SpringIoC控制反转DI 依赖注入BeanBean基础配置namescope Bean实例化方式Bean的生命周期 依赖注入方式依赖自动装配 Mybatis-Plus配置BaseMapper通用Service常用注解TableNameTableId雪花算法 TableFieldTableLogic 条件构造器和常用接口QueryWrapperUpdateWrapper 插…

【数据库原理与实践】知识点归纳(下)

第6章 规范化理论 一、关系模式设计中存在的问题 关系、关系模式、关系数据库、关系数据库的模式 关系模式看作三元组&#xff1a;R < U,F >&#xff0c;当且仅当U上的一个关系r满足F时&#xff0c;r称为关系模式R < U,F >的一个关系 第一范式&#xff08;1NF&…

一步一步学OAK之七:通过OAK相机实现特征跟踪

目录 特征跟踪Setup 1: 创建文件Setup 2: 安装依赖Setup 3: 导入需要的包Setup 4: 定义FeatureTrackerDrawer类定义变量定义onTrackBar方法定义trackFeaturePath方法定义drawFeatures方法定义FeatureTrackerDrawer类的构造函数 Setup 5: 创建pipelineSetup 6: 创建节点创建相机…

Scrapy框架之下载中间件(详解)

目录 Scrapy中下载中间件 概念 方法 process_request(self, request, spider) 参数: process_response(self, request, response, spider) 参数 基本步骤 示例代码 注意 Scrapy 中 Downloader 设置UA 开发UserAgent下载中间件 代码 三方模块 配置模块到Settin…

Redis系列 | 分类树查询功能如何从2s优化到0.1s

大家好&#xff0c;今天我们继续来分享一个在项目开发过程中遇到的实际问题&#xff0c;这里也来梳理并总结一下我们是如何对它进行持续优化的&#xff0c;希望能对大家有所帮助。 分类树查询功能&#xff0c;在各个业务系统中可以说随处可见&#xff0c;特别是在一些电商系统中…

UGUI无线滑动列表

在游戏开发中&#xff0c;经常会遇到需要展示大量数据的情况&#xff0c;例如排行榜、背包等。为了优化显示效果和性能&#xff0c;一个常见的做法是使用无限滑动列表&#xff08;Infinite Scroll View&#xff09;。本文将详细解析如何实现无限滑动列表。 基本原理 无限滑动列…