1.从html前端接收post请求,

几个name的,分为三块,一个top(top),一个content(id_body1{{}},id_body1{{}},这是个表,行数多{{}}里面数字增加),一个1bottom(bottom_text)

\diary\diary\templates\detail.html
 {# form post  #}
                    <form id="frm" method="post" action="">
                        {% csrf_token %}
                        <!-- 文本区域 -->
                        <textarea class=" col-12" id="textarea_top" name="top" required data-processed="0"
                                  data-external-plugin-resources="[]"
                                  style="background: yellow; margin-bottom: 1em; box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.1), 0 0 8px rgba(82, 168, 236, 0.6);">{{ diary.top_text }}</textarea>

                        <table id="mytable" cellspacing="0px" border="3" bordercolor="black">
                            <tr>
                                <td class="s_top">任务列表</td>
                                <td class="s_top">备注</td>
                            </tr>
                            {% for i, j in content %}
                                {% if i != 'top' and i != 'bottom' %}
                                    <tr>
                                        <td class="s1"><textarea cols="73" id="id_body1{{ forloop.counter0 }}" rows="2"
                                                                 required
                                                                 data-processed="0"
                                                                 data-external-plugin-resources="[]" data-id="id_body"

                                                                 name="value{{ forloop.counter0 }}"
                                                                 style="overflow-y: hidden; vertical-align:top; resize:none; border: none">{{ i }}</textarea>
                                        <td class="s2"><textarea cols=73" id="id_body2{{ forloop.counter0 }}" rows="2"
                                                                 required
                                                                 data-processed="0"
                                                                 data-external-plugin-resources="[]" data-id="id_body"

                                                                 name="table{{ forloop.counter0 }}"
                                                                 style="overflow-y: hidden; vertical-align: center; resize:none; border: none">{{ j }}</textarea>
                                    </tr>
                                    </tr>
                                {% endif %}
                            {% endfor %}
                        </table>
                        <br>
                        {{ comment_form.media }}
                        {{ comment_form.bottom_text }}
                        <button id="submit" type="submit" class="btn btn-primary " style="display: none">发送</button>

                    </form>

  2.view.py接收post

\diary\diary\home\views.py
    if request.method == 'POST':
        lis = []
        id = request.GET.get('id')
        diary = Diary.objects.get(id=id)

        col_len = len(eval(str(diary.content)))
        # print(table_len)
        # 获取表格多少列来获取post多少个value和table

        for i in range(col_len):
            value = request.POST.get("value" + str(i))
            table = request.POST.get("table" + str(i))
            # print(value, table)
            lis.append((value, table))
        bottom = request.POST.get("bottom_text")


        # print(request.POST)
        # print(content)
        print( lis, bottom)
     
        diary.content = lis
        diary.bottom_text = bottom
        diary.save()

 3.后端把数据发送到前端

 
\diary\diary\home\views.py
        
        id = request.GET.get('id')
        diary = Diary.objects.get(id=id)
        content = eval(str(diary.content))
       
        import json
        comment_form = DiaryForm()
        List = {'bottom_text': diary.bottom_text}

        context = {
            "content": content,
            'diary': diary,
            'bottom_text': json.dumps(List['bottom_text']),
            'comment_form': comment_form,
        }

        return render(request, 'detail.html', context=context)

4.前端接收数据,

bottom接收方式json方式接收.导入json

diary\diary\templates\detail.html和 \diary\diary\home\views.py
{#top_text#}
{{ diary.top_text }}
{#content#}
{% for i, j in content %}
{{ i }}
{{ j }}
{% endfor %}
{#bottom#}
 List = {'bottom_text': diary.bottom_text}
 context = {
        
            'bottom_text': json.dumps(List['bottom_text']),
        }
$("#id_bottom_text").val({{ bottom_text|safe }});

 

5.ajax提交,

无需刷新页面

diary\diary\templates\detail.html
<script>

        $(document).ready(function () {
            {#CKEDITOR.instances['id_bottom_text'].setData({{ bottom_text|safe }});#}
            {# 给CKeditor传入bottom_text文字#}
            $("#id_bottom_text").val({{ bottom_text|safe }});

            $("form").submit(function () {
                {#alert("提交");#}
                $.ajax({
                    url: '{% url 'home:detail' %}?id={{ diary.id }}',
                    type: 'POST',
                    data: $(this).serialize(),
                    cache: false,
                    success: function (data) {
                        console.log(data);

                        if (data['status'] == "SUCCESS") {

                            {#alert("成功")#}
                        }

                    },
                    error: function (xhr) {
                        console.log(xhr);
                    }
                });

                return false;
            })
        });

    </script>

6.让textarea自适应高度,

CKeditor还没完成自适应高度

diary\diary\templates\detail.html
<script>
        {#自动高度#}

        function makeExpandingArea(el) {
            var timer = null;
            //由于ie8有溢出堆栈问题,故调整了这里
            var setStyle = function (el, auto) {
                if (auto) el.style.height = 'auto';
                el.style.height = el.scrollHeight + 'px';
            };
            var delayedResize = function (el) {
                if (timer) {
                    clearTimeout(timer);
                    timer = null;
                }
                timer = setTimeout(function () {
                    setStyle(el)
                }, 200);
            };
            if (el.addEventListener) {
                el.addEventListener('input', function () {
                    setStyle(el, 1);
                }, false);
                setStyle(el)
            } else if (el.attachEvent) {
                el.attachEvent('onpropertychange', function () {
                    setStyle(el)
                });
                setStyle(el)
            }
            if (window.VBArray && window.addEventListener) { //IE9
                el.attachEvent("onkeydown", function () {
                    var key = window.event.keyCode;
                    if (key == 8 || key == 46) delayedResize(el);

                });
                el.attachEvent("oncut", function () {
                    delayedResize(el);
                }); //处理粘贴
            }
        }

        var textarea_top = document.getElementById('textarea_top');
        makeExpandingArea(textarea_top);

        var textarea_bottom = document.getElementById('id_bottom_text');
        makeExpandingArea(textarea_bottom);

        for (var i = 0; i < 20; i++) {
            var textarea = document.getElementById('id_body1' + i);
            makeExpandingArea(textarea);
            var textarea = document.getElementById('id_body2' + i);
            makeExpandingArea(textarea);
        }


    </script>

  7.js输入文字时同步

方法一:输入时同步,已知bug每次同步两次才可以同步最新,写code代码段.标情不会同步

\diary\diary\templates\detail.html     
     <script>
        i = 0;
        {# CKeditor输入保存 #}
        CKEDITOR.on('instanceCreated', function (e) {
            e.editor.on('contentDom', function () {
                var editable = e.editor.editable();
                editable.attachListener(editable, 'keyup', function () {
                    var content = editable.getData();
                    //执行再写入一次内容,因为保存不了最后一个字符
                     $("#id_bottom_text").val(content);
                    $("#submit").click();


                    {#alert("输入")#}
                });
            });
        });

    </script>

       <script type="text/javascript">
        const $addEvent = function (elem, eType, fn, useCapture) {
            if (elem.addEventListener) {
                elem.addEventListener(eType, fn, useCapture);
                return true;
            } else if (elem.attachEvent) {
                var r = elem.attachEvent('on' + eType, fn);
                return r;
            } else {
                elem['on' + eType] = fn;
            }
        };
        for (var i = 0; i < 20; i++) {
            {#表左边输入内容保存#}
            const element = document.getElementById('id_body1' + i);

            $addEvent(element, 'input', () => {
                {#alert("输入事件");#}
                    $("#submit").click();
                document.getElementById("showTxt").innerHTML = element.value;
            }, false);
            const element2 = document.getElementById('id_body2' + i);
            {#表右边输入保存#}
            $addEvent(element2, 'input', () => {
                    $("#submit").click();
                document.getElementById("showTxt").innerHTML = element2.value;
            }, false);
        }

    </script>

方法二:定时提交.bug页面打开两个可能同步错误

diary\diary\templates\detail.html
    <script>
        {#自动提交form表单,这个有缺陷提交ajax会跳到json页面#}
        {#                                function sub() {#}
        {#                                    var form = document.getElementById('frm');#}
        {#                                    form.submit();#}
        {#                                }#}
        {#                              setTimeout(sub, 3000);//以毫秒为单位的bai.1000代表一秒钟.根据du你需要修改这个时间.#}


        {# 比较好方案定时点击按钮,5秒点击一次#}
        setInterval(function () {
            $("#submit").click();
        }, 5000);

    </script>

8.python 快捷键打开笔记并定位今天的日记页面(加字符串匹配)

方法一:链接定位(with配合templatetags进行字符串匹配)

\blog\diary\templatetags\home_tags.py
@register.filter(name='split')
def split(value, arg):
    # 分割获取第一个url
    for path in value.split(arg):
        if path:
            # print(path)
            return path
\blog\templates\diary\nav.html
{% with request.path|split:"/" as path %}
        {# tag里面分割取得第一个,传到这里#}
        <a style="padding-right: 1em; font-size: 20px"
           href="{% if path == "yys" %} {% url 'diary:write_diary' %}{% else %}{% url 'diary:write_diary2' %}{% endif %}">写日记</a>
{% endwith %}
\blog\diary\urls.py
path('路径', views.yys_write_diary, name='write_diary'),
\blog\diary\views.py
class CreateDiary(object):
    def __init__(self, sql, region, template):

        self.sql = sql
        self.id = self.sql.objects.order_by('id').last().id
        self.diary = self.sql.objects.get(id=self.id)
        self.created = self.diary.created
        text = Template.objects.values_list(template)
        for i in text:
            if i[0]:
                self.content = i
        self.count = self.sql.objects.all().count()
        self.region = region

    def final_insert_data(self, title, top_text):
        now_time = datetime.datetime.now()
        # print("插入")
        # self.diary.title = title
        # self.diary.top_text = top_text
        # self.diary.created = now_time
        # self.diary.content = content
        # self.diary.save()

        self.sql.objects.create(
            title=title,
            top_text=top_text,
            created=now_time,
            content=self.content[0]  # django创建content带列表所以第0个,create是创建新的,save是保存更新表
        )


    def get_tile(self):
        week_day_dict = {
            0: '星期一',
            1: '星期二',
            2: '星期三',
            3: '星期四',
            4: '星期五',
            5: '星期六',
            6: '星期日',
        }
        day = datetime.datetime.now().weekday()

        get_week = week_day_dict[day]
        # 获取日期
        i = datetime.datetime.now()
        date = ("%s年%02d月%02d日" % (i.year, i.month, i.day))
        # 计算日期差
        d1 = datetime.datetime(i.year, i.month, i.day)
        d2 = datetime.datetime(2015, 5, 13)
        all_day = (d1 - d2).days
        # 获取单双周
        week = int((all_day + 2) / 7)  # 加2因为,2015年5月11号为星期一
        ji_ou = week % 2
        if ji_ou == 0:
            ji_ou = "双周"
        if ji_ou == 1:
            ji_ou = "单周"
        # 总天数是self.count + 1,计算数据库表一共多少记录
        get_message = ("(%d)【%s】%s→%s" % (self.count + 1, date, get_week, ji_ou))
        print(get_message)
        return get_message

    def get_top(self):
        try:
            text = weather.show_weather(weather.get_weather_data(self.region))
            # print(text)
            return text
        except Exception as result:
            print("未知错误 %s" % result)

    def create_diary(self):
        title = self.get_tile()
        top_text = self.get_top()
        self.final_insert_data(title, top_text)

    def cmd_copy_sql(self):
        os.system('mysqldump  -u root -p123456 yys > /home/yys.sql')  # 备份数据库sql到home文件夹下
        os.system('mysqldump yys -u root -p123456  | mysql  yys -h ip -u root -p123456')   # 复制本地到远程

    def main(self):

        # print("最后一天id:%s, 最后创建日期:%s, 日志总数为:%s" % (self.id, self.created, self.count))
        # print("相差%s天" % (datetime.datetime.now().date() - self.created.date()).days)

        if (datetime.datetime.now().date() - self.created.date()).days > 0:
            # print("要创建日记")
            threading.Thread(target=self.cmd_copy_sql).start()  # 多线程复制mysql
            self.create_diary()  # 总日记数+1
            time.sleep(2)
            self.id = self.sql.objects.order_by('id').last().id

        # 省略了else
        return self.id

def yys_write_diary(request):
    create = CreateDiary(YysDiary, '正阳', 'yys_template')
    id = create.main()
    path = reverse('diary:detail') + '?id={}'.format(id)
    return redirect(path)

方法二,python定位(推荐):

数据库查询方式记录多少天(), 1.查询标题总数2.在查询最后一条是不是今天的,3.如果今天年月日-最后创建年月日就新建一天日记,如果>0就新建一天日记

select * from tb_diary order by id DESC limit 1;

新建后标题天数为记录总数+1, 

//查询表中记录总数
select count(*) from 表名;

 

最后跳转地址id = id+1

http://127.0.0.1:5000/detail?id=id+1

如果创建年月日等于今天的,就为id=id

http://127.0.0.1:5000/detail?id=id

方法三:

通过天数定位id,用request爬取页面title.如果title为404,则今天日记不存在,则进行创建,创建时候并子线程进行远程备份和本地本分

http://127.0.0.1:5000/detail?id=天数

执行完退出bat写法

python C:\Users\yys53\OneDrive\python\bestscript\create_diary.py
exit

 9.自动换背景

\diary\home\templatetags\home_tags.py
import random

from django import template

register = template.Library()


@register.simple_tag
def get_random(obj):
    rand = random.randint(1, 7)
    pic = 'backgroundpic/bg{}.jpg'.format(rand)
    # print(pic)
    return pic

 

\diary\templates\base.html

{% load home_tags %}
<style>
        body {
        {% get_random diary as rand %}
        {% with rand as image_static %}
            background: url("{% static image_static %}");

        {% endwith %}
            width: 100%;
            height: 100%;
            top: 0;
            left: 0;
            background-attachment: fixed;
            background-size: 100%;
        }
</style>

10.点击自动获取时间

                                     <td id="td_{{ forloop.counter0 }}"
                                        style="background: rgba(144,238,144,0.7);position: relative; "><textarea
                                            class="id_body2"
                                            id="id_body2{{ forloop.counter0 }}"
                                            rows="1"
                                            data-processed="0"
                                            data-external-plugin-resources="[]"
                                            data-id="id_body"
                                            name="table{{ forloop.counter0 }}"
                                            {% if today != create_day %} disabled {% endif %}
                                    >{{ j }}</textarea>
                                        <div class="get_clock" id="btn{{ forloop.counter0 }}"
                                             onClick="copyFn('id_body2' + {{ forloop.counter0 }} )">⏰
                                        </div>

 

div.get_clock {
    position: absolute;
    left: -10px;
    top: 2px;
    display: none;
    cursor: pointer
}

    <script>
        $(function () {
            {#首先获取所有的pre,可以判断多少个id1_#}
            var pre_ls = document.getElementsByTagName('td');
            for (var k = 0; k < pre_ls.length; k++) {
                (function () {
                    var index = k;
                    $('#td_' + index).hover(function () {
                        $(this).find('div').show();
                        $(this).css({"background":"rgba(23,234,56, 0.7)"}); //设置悬浮背景色
                        document.getElementById("btn"+index).accessKey = "t";   //设置快捷键
                    }, function () {
                        $(this).find('div').hide();
                        $(this).css({"background":"rgba(144,238,144,0.7)"}); //悬浮立刻背景色
                        document.getElementById("btn"+index).accessKey = ""; //快捷键设置为空,不然有冲突

                    });
                })(k)
            }
        });

        function copyFn(element) {
            {#追加时间#}
            var ele = document.getElementById(element);
            ele.value = ele.value + new Date().toLocaleTimeString();
            {#保存#}
            $("#submit").click();
        }

    </script>

 

总结失败原因:

1.当ajax总是跳到json页面,原因submit与其他js脚本冲突(像梁山好汉表格,注释掉),一般解决开发者工具console报错解决

2.CKeditor不显示可能插件冲突,prism没有文件部署好

3.CKeditor搭建参考前面笔记Django 富文本CKEditor

4.如果textarea提示请填写此字段,去掉required

5. 让今天日记可以编辑,其他日期内容不能编辑,如果content或top_text没有内容则隐藏注意对应js也要隐藏,不然由bug

6.把txt文本写入mysql,created时间形成:减去所有日记天数,从2015年如果每天+1,一直加到今天为止

time = datetime.datetime.now()+datetime.timedelta(days=-1894)

 

t = time + datetime.timedelta(days=+add)

6.如果打开两个页面都是今天的日记,一个填写另一个不写,会有冲突,会一起提交,一个空一个不空(解决办法js自动保存)