• DAY 80 git02


    1 git的操作基本操作
    -三个区:工作区,暂存区,版本库
       -git add .
       -git commit -m ‘注释’
       -工作区改了内容(改的是被版本管理的内容)git checkout .
       -工作区回复到某个版本: git reset --hard 版本号
       -从暂存区拉回工作区:git reset .
       -git status
       -git log
       -git reflog
     
    2 忽略文件
    -在项目根路径下建立.gitignore
       -在文件中写内容
      log    忽略所有log文件夹
           /log   忽略根路径下的log
           *      任意长度的字符
           *.log  忽略以.log结尾的文件
           /luffyapi/apps
      -咱们写的
          .idea
           *.log
           scripts
           __pycache__
           #luffyapi/apps/*/migrations
           */*/*/migrations/*.py
           !*/*/*/migrations/__init__.py
           
    3 分支
    -查:git branch   #*和绿色在哪,表示在当前分支
    -增:git branch dev
       -删:git branch -D dev # 不在该分支才能删除
       -切换:git checkout dev
       -合并:git merge dev   # 往我身上合并,不要在dev分支执行
    4 pycharm操作git
    -使用pycharm新建,删除,切换分支
       -初始化仓库
       -提交到暂存区
       -提交到版本库
       -建立远程仓库
       
    5 远程仓库
    -查看远程仓库 git remote
       -新增远程仓库 git remote add 远程仓库名字 远程地址
       -把代码提交到远程仓库 git push 远程仓库名字 分支名
       -从远程仓库拉取代码  git pull origin master
       
    6 ssh连接远程仓库
    -非对称加密(对称加密)
    -本地生成公钥私钥(用户家路径生成.ssh文件夹,公钥和私钥)
       -拿着公钥配置在gitee的ssh里面
       -以后再提交使用ssh方式提交(remote地址得改)

     

    1 协同开发

    1 多人开发同一个项目
    2 现在你们git clone 项目,在你本地了
    3 可以改代码了,当你git  push 的时候,提交不了
    4 项目管理员分配给你权限(gitee中管理--》仓库成员--》邀请成员)
    5 这一个项目有一个管理员,若干开发者
    6 重点:不能夸版本提交,只能先拉到最新,再提交
    7 如果某个开发者再s1.py 的第14行加入了东西,我也加入了,他先提交(它没问题)
    8 当我再拉取,出冲突了
       <<<<<<< HEAD
       你的代码
      =======
       同事的代码
       >>>>>>> d78b8fb39f6469e810868218a052bc3174b3e1fc

    9 解决冲突
    -留你的代码:你写的好
       -留他的代码:你觉得他写的好
       -你们的都留着:你俩虽然改了一行,但是功能不一样

     

    2 分支合并

    1 版本库又两套
    -本地一套
      -本地有master,dev分支
       -远程一套
      -远程现在只有master分支
    2 把本地dve提交到远端
    git push origin dev
       现在远端有两个分支 master和dev
    3 删除本地分支,删除远程分支(点点点)

    4 直接在远程创建分支(点点点)
    5 把远端的dev拉到本地

     

    2.1 线上分支合并

    1 在线上新建一个dev1分支
    2 拉去到本地
    3 在本地dev1分支增加一行代码,提交到版本库
    4 在本地dev1分支又增加一行代码,提交到版本库
    5 远程分支合并
    -pull request,指定从哪个分支合并到哪个分支
       -绿色表示没有冲突,可以正常合并
       -普通和扁平化(变基)
    6 本地、远程的dev1和master就完全一样了

     

     

    2.2 线下分支合并提交

    1 本地dev1分支新增代码,提交到版本库
    2 本地dev1分支合并到master
    -切到master
       -git merge dev1 (没有冲突直接合并)
       -git push origin master (本地master提交到远端master)
    3 切到dev1分支,再提交到远端
    4 到此,本地分支合并完成,远端的dev1跟master完全一样,本地的dev1跟master也完全一样

     

    2.3 合并分支冲突解决

    1 再master加一行,提交到版本库
    2 再dev1同样尾增增加一行,提交到版本库
    3 把dev1合并到master,就会出冲突
    -切到master分支
       -git merge dev1  有冲突
       -解决冲突(到底留什么,你觉得)
       -提交到远端

     

     

    3 远程仓库回滚

    1 远程仓库,回到最初路飞第一次提交的地方
    2 再本地回复到第一次提交
    git reste --hard 59dbf80c
       git push origin master -f # 强制提交
       
    3 切记 -f 清醒的时候使用

     

     

    4 其他了解

    git flow
    -是一种建分支的方案
       -预览分支,开发分支,bug分支,主分支,测试分支...
    pull和fetch区别
    git pull:拉代码+合并
       git fetch:拉代码,需要手动合进去
    变基rebase
    -合并分支的时候,是否保留之前分支的日志
       
       
    git客户端:
    -官方下载的一个(命令行下)
       -pycharm编辑器
       -sourcetree:美观,分支通过不同颜色线上,看着好看

    5 登陆页面分析

    <template>
    <div class="login">
    <span @click="close_login">X</span>
    </div>
    </template>

    <script>
    export default {
    name: "Login",
    methods:{
    close_login(){
    //子传父组件 this.$emit,给父组件传递一个事件
    this.$emit("close")
    },

    },

    }
    </script>

    <style scoped>
    .login{
    100vw;
    height: 100vw;
    position: fixed;
    left: 0;
    top: 0;
    z-index: 666;

    }
    span{
    font-size: 30px;
    cursor: pointer;
    }
    </style>

     

    6 前端登陆注册编写

    Login.vue

    <template>
    <div class="login">
    <div class="box">
    <i class="el-icon-close" @click="close_login"></i>
    <div class="content">
    <div class="nav">
    <span :class="{active: login_method === 'is_pwd'}"
    @click="change_login_method('is_pwd')">密码登录</span>
    <span :class="{active: login_method === 'is_sms'}"
    @click="change_login_method('is_sms')">短信登录</span>
    </div>
    <el-form v-if="login_method === 'is_pwd'">
    <el-input
    placeholder="用户名/手机号/邮箱"
    prefix-icon="el-icon-user"
    v-model="username"
    clearable>
    </el-input>
    <el-input
    placeholder="密码"
    prefix-icon="el-icon-key"
    v-model="password"
    clearable
    show-password>
    </el-input>
    <el-button type="primary">登录</el-button>
    </el-form>
    <el-form v-if="login_method === 'is_sms'">
    <el-input
    placeholder="手机号"
    prefix-icon="el-icon-phone-outline"
    v-model="mobile"
    clearable
    @blur="check_mobile">
    </el-input>
    <el-input
    placeholder="验证码"
    prefix-icon="el-icon-chat-line-round"
    v-model="sms"
    clearable>
    <template slot="append">
    <span class="sms" @click="send_sms">{{ sms_interval }}</span>
    </template>
    </el-input>
    <el-button type="primary">登录</el-button>
    </el-form>
    <div class="foot">
    <span @click="go_register">立即注册</span>
    </div>
    </div>
    </div>
    </div>
    </template>

    <script>
    export default {
    name: "Login",
    data() {
    return {
    username: '',
    password: '',
    mobile: '',
    sms: '',
    login_method: 'is_pwd',
    sms_interval: '获取验证码',
    is_send: false,
    }
    },
    methods: {
    close_login() {
    this.$emit('close')
    },
    go_register() {
    this.$emit('go')
    },



    change_login_method(method) {
    this.login_method = method;
    },
    check_mobile() {
    if (!this.mobile) return;
    if (!this.mobile.match(/^1[3-9][0-9]{9}$/)) {
    this.$message({
    message: '手机号有误',
    type: 'warning',
    duration: 1000,
    onClose: () => {
    this.mobile = '';
    }
    });
    return false;
    }
    this.is_send = true;
    },
    send_sms() {

    if (!this.is_send) return;
    this.is_send = false;
    let sms_interval_time = 60;
    this.sms_interval = "发送中...";
    let timer = setInterval(() => {
    if (sms_interval_time <= 1) {
    clearInterval(timer);
    this.sms_interval = "获取验证码";
    this.is_send = true; // 重新回复点击发送功能的条件
    } else {
    sms_interval_time -= 1;
    this.sms_interval = `${sms_interval_time}秒后再发`;
    }
    }, 1000);
    }
    }
    }
    </script>

    <style scoped>
    .login {
    100vw;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 10;

    }

    .box {
    400px;
    height: 420px;

    border-radius: 10px;
    position: relative;
    top: calc(50vh - 210px);
    left: calc(50vw - 200px);
    }

    .el-icon-close {
    position: absolute;
    font-weight: bold;
    font-size: 20px;
    top: 10px;
    right: 10px;
    cursor: pointer;
    }

    .el-icon-close:hover {
    color: darkred;
    }

    .content {
    position: absolute;
    top: 40px;
    280px;
    left: 60px;
    }

    .nav {
    font-size: 20px;
    height: 38px;
    border-bottom: 2px solid darkgrey;
    }

    .nav > span {
    margin: 0 20px 0 35px;
    color: darkgrey;
    user-select: none;
    cursor: pointer;
    padding-bottom: 10px;
    border-bottom: 2px solid darkgrey;
    }

    .nav > span.active {
    color: black;
    border-bottom: 3px solid black;
    padding-bottom: 9px;
    }

    .el-input, .el-button {
    margin-top: 40px;
    }

    .el-button {
    100%;
    font-size: 18px;
    }

    .foot > span {
    float: right;
    margin-top: 20px;
    color: orange;
    cursor: pointer;
    }

    .sms {
    color: orange;
    cursor: pointer;
    display: inline-block;
    70px;
    text-align: center;
    user-select: none;
    }
    </style>

     

    Register.vue

    <template>
    <div class="register">
    <div class="box">
    <i class="el-icon-close" @click="close_register"></i>
    <div class="content">
    <div class="nav">
    <span class="active">新用户注册</span>
    </div>
    <el-form>
    <el-input
    placeholder="手机号"
    prefix-icon="el-icon-phone-outline"
    v-model="mobile"
    clearable
    @blur="check_mobile">
    </el-input>
    <el-input
    placeholder="密码"
    prefix-icon="el-icon-key"
    v-model="password"
    clearable
    show-password>
    </el-input>
    <el-input
    placeholder="验证码"
    prefix-icon="el-icon-chat-line-round"
    v-model="sms"
    clearable>
    <template slot="append">
    <span class="sms" @click="send_sms">{{ sms_interval }}</span>
    </template>
    </el-input>
    <el-button type="primary">注册</el-button>
    </el-form>
    <div class="foot">
    <span @click="go_login">立即登录</span>
    </div>
    </div>
    </div>
    </div>
    </template>

    <script>
    export default {
    name: "Register",
    data() {
    return {
    mobile: '',
    password: '',
    sms: '',
    sms_interval: '获取验证码',
    is_send: false,
    }
    },
    methods: {
    close_register() {
    this.$emit('close', false)
    },
    go_login() {
    this.$emit('go')
    },
    check_mobile() {
    if (!this.mobile) return;
    if (!this.mobile.match(/^1[3-9][0-9]{9}$/)) {
    this.$message({
    message: '手机号有误',
    type: 'warning',
    duration: 1000,
    onClose: () => {
    this.mobile = '';
    }
    });
    return false;
    }
    this.is_send = true;
    },
    send_sms() {
    if (!this.is_send) return;
    this.is_send = false;
    let sms_interval_time = 60;
    this.sms_interval = "发送中...";
    let timer = setInterval(() => {
    if (sms_interval_time <= 1) {
    clearInterval(timer);
    this.sms_interval = "获取验证码";
    this.is_send = true; // 重新回复点击发送功能的条件
    } else {
    sms_interval_time -= 1;
    this.sms_interval = `${sms_interval_time}秒后再发`;
    }
    }, 1000);
    }
    }
    }
    </script>

    <style scoped>
    .register {
    100vw;
    height: 100vh;
    position: fixed;
    top: 0;
    left: 0;
    z-index: 10;

    }

    .box {
    400px;
    height: 480px;

    border-radius: 10px;
    position: relative;
    top: calc(50vh - 240px);
    left: calc(50vw - 200px);
    }

    .el-icon-close {
    position: absolute;
    font-weight: bold;
    font-size: 20px;
    top: 10px;
    right: 10px;
    cursor: pointer;
    }

    .el-icon-close:hover {
    color: darkred;
    }

    .content {
    position: absolute;
    top: 40px;
    280px;
    left: 60px;
    }

    .nav {
    font-size: 20px;
    height: 38px;
    border-bottom: 2px solid darkgrey;
    }

    .nav > span {
    margin-left: 90px;
    color: darkgrey;
    user-select: none;
    cursor: pointer;
    padding-bottom: 10px;
    border-bottom: 2px solid darkgrey;
    }

    .nav > span.active {
    color: black;
    border-bottom: 3px solid black;
    padding-bottom: 9px;
    }

    .el-input, .el-button {
    margin-top: 40px;
    }

    .el-button {
    100%;
    font-size: 18px;
    }

    .foot > span {
    float: right;
    margin-top: 20px;
    color: orange;
    cursor: pointer;
    }

    .sms {
    color: orange;
    cursor: pointer;
    display: inline-block;
    70px;
    text-align: center;
    user-select: none;
    }
    </style>

    Header.vue

    <template>

    <div>
    <div class="slogan">
    <p>老男孩IT教育 | 帮助有志向的年轻人通过努力学习获得体面的工作和生活</p>
    </div>
    <div class="nav">
    <ul class="left-part">
    <li class="logo">
    <router-link to="/">
    <img src="../assets/img/head-logo.svg" alt="">
    </router-link>
    </li>
    <li class="ele">
    <span @click="goPage('/free-course')" :class="{active: url_path === '/free-course'}">免费课</span>
    </li>
    <li class="ele">
    <span @click="goPage('/actual-course')" :class="{active: url_path === '/actual-course'}">实战课</span>
    </li>
    <li class="ele">
    <span @click="goPage('/light-course')" :class="{active: url_path === '/light-course'}">轻课</span>
    </li>
    </ul>

    <div class="right-part">
    <div>
    <span @click="put_login">登录</span>
    <span class="line">|</span>
    <span @click="put_register">注册</span>


    </div>
    </div>


    <Login v-if="is_login" @close="close_login" @go="put_register"/>
    <Register v-if="is_register" @close="close_register" @go="put_login"/>
    </div>

    </div>
    </template>

    <script>
    import Login from "../components/Login";
    import Register from "../components/Register";

    export default {
    name: "Header",
    data() {
    return {
    is_login: false,
    is_register: false,
    }
    },
    methods: {
    put_login() {
    this.is_login = true;
    this.is_register = false;
    },
    put_register() {
    this.is_login = false;
    this.is_register = true;
    },
    close_login() {
    this.is_login = false;
    },
    close_register() {
    this.is_register = false;
    }

    },
    components: {
    Login, Register
    }
    }
    </script>

    <style scoped>
    .header {

    box-shadow: 0 0 5px 0 #aaa;
    }

    .header:after {
    content: "";
    display: block;
    clear: both;
    }

    .slogan {

    height: 40px;
    }

    .slogan p {
    1200px;
    margin: 0 auto;
    color: #aaa;
    font-size: 13px;
    line-height: 40px;
    }

    .nav {

    user-select: none;
    1200px;
    margin: 0 auto;

    }

    .nav ul {
    padding: 15px 0;
    float: left;
    }

    .nav ul:after {
    clear: both;
    content: '';
    display: block;
    }

    .nav ul li {
    float: left;
    }

    .logo {
    margin-right: 20px;
    }

    .ele {
    margin: 0 20px;
    }

    .ele span {
    display: block;
    font: 15px/36px '微软雅黑';
    border-bottom: 2px solid transparent;
    cursor: pointer;
    }

    .ele span:hover {
    border-bottom-color: orange;
    }

    .ele span.active {
    color: orange;
    border-bottom-color: orange;
    }

    .right-part {
    float: right;
    }

    .right-part .line {
    margin: 0 10px;
    }

    .right-part span {
    line-height: 68px;
    cursor: pointer;
    }
    </style>

    7 登录注册接口分析

    1 多方式登录接口
    2 校验手机号是否存在接口
    3 手机号,密码,验证码注册接口
    4 短信登录接口
    5 发送短信接口(阿里大于短信,腾信的短信平台(刚注册免费100条))

    8 多方式登录接口

    路由

     


    from django.urls import path,include
    from . import views

    from rest_framework.routers import SimpleRouter
    router=SimpleRouter()
    # /user/login 的post请求
    router.register('',views.LoginView,'login')
    urlpatterns = [

    path('', include(router.urls)),

    ]

    序列化类

    from rest_framework import serializers
    from rest_framework.exceptions import ValidationError
    from . import models
    from rest_framework_jwt.settings import api_settings

    jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
    jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER


    class UserModelSerializer(serializers.ModelSerializer):
    # 必须重写一下username字段
    username = serializers.CharField()

    class Meta:
    model = models.User
    fields = ['username', 'password']
    extra_kwargs = {
    'username': {'write_only': True},
    'password': {'write_only': True},

    }

    # 写全局钩子(校验用户名密码是否正确,登录成功,签发token)
    def validate(self, attrs):
    # 取出用户名密码
    username = attrs.get('username')
    password = attrs.get('password')
    import re
    if re.match('^1[3-9][0-9]{9}$', username):
    user = models.User.objects.filter(mobile=username).first()
    elif re.match('^.+@.+$', username):
    user = models.User.objects.filter(email=username).first()
    else:
    user = models.User.objects.filter(username=username).first()
    # 校验user,校验密码
    if user and user.check_password(password):
    # 签发token
    payload = jwt_payload_handler(user)
    token = jwt_encode_handler(payload)
    self.context['token'] = token
    self.context['user'] = user
    return attrs

    else:
    raise ValidationError('用户名或密码错误')

    视图类

    from rest_framework.viewsets import ViewSetMixin,ViewSet
    from rest_framework.views import APIView
    from rest_framework.decorators import action
    from .serializer import UserModelSerializer
    # class LoginView(ViewSetMixin,APIView):
    class LoginView(ViewSet):
    @action(methods=['POST'],detail=False)
    def login(self,request,*args,**kwargs):
    # 序列化类
    ser=UserModelSerializer(data=request.data)
    if ser.is_valid():
    # 登录成功
    token=ser.context['token']
    user=ser.context['user']
    # ser2=UserModelSerializer(instance=user)
    return APIResponse(token=token,username=user.username,id=user.id)
    else:
    # 登录失败
    return APIResponse(code=101,msg=ser.errors)
  • 相关阅读:
    USACO--2.1The Castle
    浅谈python字符串存储形式
    面向对象——一起来复习托付与事件!
    数据结构——算法之(032)(求两个串中的第一个最长子串)
    读《浪潮之巅》有感
    关于android 怎样安装 assets文件下的apk
    每日一小练——求质数
    怎样使破解网页的禁止复制黏贴
    Angularjs Nodejs Grunt 一个样例
    《TCP/IP具体解释卷2:实现》笔记--域和协议
  • 原文地址:https://www.cnblogs.com/DEJAVU888/p/14893930.html
Copyright © 2020-2023  润新知