blog

manage.py

djangoday4

|–__init.py
|–settings.py
import os

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

SECRET_KEY = '1mq(+w3p$tsx%sp!o5hvoeq8r4u5rk-w8#xpsk+xs28l*60)(2'

DEBUG = True

ALLOWED_HOSTS = ["*"]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    # 'middleware.MyMiddleware.MiddleWare2',
    # 'middleware.MyMiddleware.MiddleWare1',

]

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'user.apps.UserConfig',
    'captcha',
    'article',
    'xadmin',  # xadmin
    'crispy_forms',  # xadmin
    'ckeditor',  # 添加ckeditor富文本编辑器
    'ckeditor_uploader'  #ckeditor进行文件上传

]

ROOT_URLCONF = 'djangoday4.urls'

# 如果用户继承了AbstractUser,修改auth_user的模型
AUTH_USER_MODEL = 'user.UserProfile'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
                'django.template.context_processors.media',  # 在模板中可以使用{{ MEDIA_URL }}
            ],
        },
    },
]

WSGI_APPLICATION = 'djangoday4.wsgi.application'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'blog',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        'PORT': 3306
    }
}

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]

LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
USE_I18N = True
USE_L10N = True
USE_TZ = False

STATIC_URL = '/static/'
STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
# STATIC_ROOT = os.path.join(BASE_DIR, 'static')

MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
CKEDITOR_UPLOAD_PATH = "uploads/"

# 发送邮件的设置
EMAIL_HOST = 'smtp.126.com'
EMAIL_HOST_USER = 'student1902@126.com'
EMAIL_HOST_PASSWORD = 'student1902'
EMAIL_PORT = 25
EMAIL_USE_TLS = True
EMAIL_USE_SSL = False  # 126,QQ: 465   163:454

# 添加一个登陆路由  结合  @login_required
LOGIN_URL = '/user/login'
|–urls.py
import ckeditor_uploader
from django.contrib import admin
from django.urls import path, include, re_path
from django.views.static import serve

import xadmin
from djangoday4.settings import MEDIA_ROOT
from user.views import index

urlpatterns = [
    path('xadmin/', xadmin.site.urls),
    path('', index, name='index'),
    path('user/', include('user.urls', namespace='user')),
    path('article/', include('article.urls', namespace='article')),
    re_path(r'^captcha/', include('captcha.urls')),
    re_path(r'^media/(?P<path>.*)$', serve, {'document_root': MEDIA_ROOT}),
    # 加载ckeditor的urls
    re_path(r'^ckeditor/', include('ckeditor_uploader.urls')),

]

|–wsgi.py
import os

from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "djangoday4.settings")

application = get_wsgi_application()

middleware

|–__init.py
|–MyMiddleware.py
from django.shortcuts import render, redirect
from django.urls import reverse
from django.utils.deprecation import MiddlewareMixin

'''
        # print(request.META)
        # remote_host = request.META['REMOTE_HOST']
        # print(remote_host)
        print(request.path)
        # request对象 ----》就是view function 函数的request
        print(request.url)
'''
login_list = ['/user/center', ]


class MiddleWare1(MiddlewareMixin):
    # 重写方法
    # 处理的是request请求
    def process_request(self, request):
        print('------------->1')
        print(request.META['REMOTE_ADDR'])
        path = request.path
        if path in login_list:
            print(request.user)  # AnonymousUser  未登录
            print(type(request.user))
            print(request.user.username)  # 认为就是用户登录的对象
            if not request.user.is_authenticated:
                return redirect(reverse('user:login'))
    # 进入view之前调用的函数
    def process_view(self, request, callback,callback_args, callback_kwargs):
        print('callback_args:',callback_args)
        print('callback_kwargs:',callback_kwargs)
        print('------------->view',callback)
        # callback(request,callback_args,callback_kwargs)

    # render(request,'xxx.html')
    def process_template_response(self):
        pass

    def process_exception(self,request, exception):
        pass


    # 处理的是响应
    def process_response(self, request, response):
        print('==============>response')
        return response


class MiddleWare2(MiddlewareMixin):
    # 重写方法
    def process_request(self, request):
        print('------------->2')

static

media

templates

|–base.html

{% load staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}
        达达个人博客 - 一个站在web前端设计之路的技术员个人博客网站
    {% endblock %}</title>
    <meta name="keywords" content="个人博客,达达个人博客,个人博客模板,达达"/>
    <meta name="description" content="达达个人博客,是一个站在web前端设计之路的程序员个人网站,提供个人博客模板免费资源下载的个人原创网站。"/>
    <link href="{% static 'css/base.css' %}" rel="stylesheet">
    <link href="{% static 'css/index.css' %}" rel="stylesheet">
    <!--[if lt IE 9]>
    <script src="{% static 'js/modernizr.js' %}"></script>
    <![endif]-->
    <script src="{% static 'js/scrollReveal.js' %}"></script>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    {% block mycss %}

    {% endblock %}
</head>
<body>
<header>
    <div style="text-align: right;padding-top: 20px;padding-right:10px;font-size: 18px;">
        {% if request.user.is_authenticated %}
            欢迎!<a href="{% url 'user:center' %}">{{ request.user.username }}</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <a href="{% url 'user:logout' %}">注销</a>
        {% else %}
            <a href="{% url 'user:login' %}"> 登录</a> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <a href="{% url 'user:register' %}">注册</a>
        {% endif %}
    </div>
    <div class="logo" data-scroll-reveal="enter right over 1s"><a href="/"><img
            src="{% static 'images/logo.png' %}"></a></div>

    <nav class="topnav" data-scroll-reveal="enter bottom over 1s after 1s">
        <a href="{% url 'index' %}"><span>首页</span><span class="en">Home</span></a>
        <a href="{% url 'article:write' %}"><span>写博客</span><span class="en">Life</span></a>
        <a href="{% url 'article:show' %}"><span>学无止境</span><span class="en">Learn</span></a>
        <a href="learn.html"><span>关于我</span><span class="en">About</span></a>
        <a href="{% url 'user:center' %}"><span>个人资料</span><span class="en">Detail</span></a>
        <a href="{% url 'article:message' %}"><span>留言</span><span class="en">Saying</span></a></nav>
</header>

<article>
    <div class="container">
        {% block content %}

        {% endblock %}
    </div>
</article>

<footer>
    Design by DanceSmile <a href="/">京ICP备11111111号-1</a>
</footer>
<script>
    if (!(/msie [6|7|8|9]/i.test(navigator.userAgent))) {
        (function () {
            window.scrollReveal = new scrollReveal({reset: true});
        })();
    }
    ;
</script>
{% block myjs %}

{% endblock %}
</body>
</html>
|–index.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block content %}
    <div class="blog" data-scroll-reveal="enter top">
        {% for figure_article in figure_articles %}
            <figure>
                <ul>
                    <a href="{% url 'article:detail' %}?id={{ figure_article.id }}"><img
                            src="{{ MEDIA_URL }}{{ figure_article.image }}"><span>点击查看详情</span></a>
                </ul>
                <p><a href="{% url 'article:detail' %}?id={{ figure_article.id }}">{{ figure_article.title }}</a></p>
                <figcaption>
                    {{ figure_article.desc }}
                </figcaption>
            </figure>
        {% endfor %}
    </div>
    <ul class="cbp_tmtimeline">
        {% for darticle in darticles %}
            <li>
                <time class="cbp_tmtime"><span>{{ darticle.date | date:'m-d' }}</span>
                    <span>{{ darticle.date | date:'Y' }}</span></time>
                <div class="cbp_tmicon"></div>
                <div class="cbp_tmlabel" data-scroll-reveal="enter right over 1s">
                    <h2>{{ darticle.title }}</h2>
                    <p><span class="blogpic"><a href="{{ MEDIA_URL }}{{ darticle.image }}"><img
                            src="{{ MEDIA_URL }}{{ darticle.image }}"></a></span>
                        {{ darticle.desc }}</p>
                    <a href="{% url 'article:detail' %}?id={{ darticle.id }}" target="_blank" class="readmore">阅读全文&gt;&gt;</a>
                </div>
            </li>
        {% endfor %}
    </ul>
{% endblock %}
|–article
|–info.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
    详情
{% endblock %}
{% block mycss %}
    <link href="{% static 'css/info.css' %}" rel="stylesheet">
    <link href="{% static 'css/m.css' %}" rel="stylesheet">
{% endblock %}

{% block content %}
    <div class="infos">
        <div class="newsview">
            <h2 class="intitle">您现在的位置是:<a href="/">网站首页</a>&nbsp;&gt;&nbsp;<a href="/">学无止境</a></h2>

            <h3 class="news_title">{{ article.title }}</h3>
            <div class="news_author"><span class="au01">{{ article.user.username }}</span><span
                    class="au02">{{ article.date }}</span><span class="au03">共<b>{{ article.click_num }}</b>人围观</span>
            </div>
            <div class="tags">
                {% for tag in article.tags.all %}
                    <a href="/">{{ tag.name }}</a>
                {% endfor %}
            </div>
            <div class="news_about"><strong>简介</strong>{{ article.desc }}
            </div>
            <div class="news_infos">
                {{ article.content| safe }}
                <p>
                    矛盾了很长时间,莱伊恩终于想到了一条妙计,他在大厅里加了四根柱子,但它们并未与天花板连接,只不过是装装样子,糊弄那些刚愎自用的家伙。这个秘密始终没有被发现。直到300多年后市政府准备修缮大厅天花板时,才发现莱伊恩的“弄虚作假”。我们每个人都想得到别人的尊敬,尤其有了一定的社会地位的人,更想得到别人尊重。建筑设计师克里斯托·莱伊恩很明白这一点,当市政府权威人士对他的建筑设计提出疑问时,他并不坚持己见,而是让市政府权威人士感到他对他们很尊重。所以,一个聪明的人,不仅能维护自己的尊严,还能够顾及他人的尊严。</p>
                <p><img src="{% static 'images/v2.jpg' %}"></p>
                <p>莱伊恩的故事,向我们讲述了一个深刻的哲理“恪守着自己的原则,哪怕遭遇到最大的阻力,也要想办法抵达胜利。”</p>
                <p>
                    就拿我自己来说吧,有时候会很矛盾,设计好的作品,不把它分享出来,会觉得待在自己电脑里面实在是没有意义。干脆就发布出去吧。我也害怕收到大家不好的评论,有些评论,可能说者无意,但是对于每一个用心的站长来说,都会受很深的影响,愤怒,恼羞。</p>
                <p>心态很重要,再来看莱伊恩,他当时顶着多大的压力呀。同样作为一个前端设计师,哪怕遭到质疑,我们也要像莱伊恩一样恪守自己的原则。</p>
            </div>
        </div>
    </div>
    <div class="nextinfo">
        <p>上一篇:<a href="{% url 'article:detail' %}?id={{ article.id |add:'-1' }}">传微软将把入门级Surface平板价格下调150美元</a></p>
        <p>下一篇:<a href="{% url 'article:detail' %}?id={{ article.id|add:'1' }}">云南之行——大理洱海一日游</a></p>
    </div>
    <div class="otherlink">
        <h2>相关文章</h2>
        <ul>
            {% for artcileabout in list_about %}
                <li><a href="{% url 'article:detail' %}?id={{ artcileabout.id }}"
                       title="云南之行——丽江古镇玉龙雪山">{{ artcileabout.title }}</a></li>
            {% endfor %}


        </ul>
    </div>
    <div class="news_pl">
        <h2>文章评论</h2>
        <ul>
            {% for comment in comments %}
                <li>
                    <p><span>{{ comment.nickname }}</span> <span>{{ comment.date }}</span></p>
                    <p>{{ comment.content }}</p>
                </li>
            {% endfor %}


        </ul>
        <div id="plpost">
            <p><span>来说句话吧....</span> <span>共有评论数:{{ comments.count }}条</span></p>

            <p><input type="text" name="uname" id="uname" placeholder="输入用户昵称"></p>
            <p>
                <textarea name="saytext" id="saytext" cols="80" rows="6">

                </textarea>
            </p>
            <p><input type="submit" value="评论" id='btncomment'></p>

        </div>
    </div>

{% endblock %}

{% block myjs %}
    <script>
        $(function () {
            // 得到按钮对象
            $('#btncomment').click(function () {
                //从文本框中取值
                var nickname = $('#uname').val();
                var saytext = $('#saytext').val();
                //发出请求
                $.getJSON('{% url 'article:comment' %}', {
                    nickname: nickname,
                    saytext: saytext,
                    aid: '{{ article.id }}'
                }, function (data) {
                    if(data.status==1){
                        window.location.href='{% url 'article:detail' %}?id={{ article.id }}'
                    }
                })
            });
        });

    </script>
{% endblock %}


|–learn.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
    学无止境
{% endblock %}
{% block mycss %}
    <!-- css files -->

    <!-- Online-fonts -->
    <link href="//fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&amp;subset=latin-ext,vietnamese"
          rel="stylesheet">
    <!-- //Online-fonts -->
    <link href="{% static 'css/learn.css' %}" rel="stylesheet">
{% endblock %}

{% block content %}
    <h2 class="ctitle"><b>学无止境</b> <span>不要轻易放弃。学习成长的路上,我们长路漫漫,只因学无止境。</span></h2>
    <div class="rnav">
        <ul>
            {% for tag in tags %}
                <li><a href="{% url 'article:show' %}?tid={{ tag.id }}&page=1">{{ tag.name }}</a></li>
            {% endfor %}
        </ul>
    </div>
    <ul class="cbp_tmtimeline">
        {% for article in page.object_list %}
            <li>
                <time class="cbp_tmtime"><span>{{ article.date|date:'m-d' }}</span>
                    <span>{{ article.date|date:"Y" }}</span></time>
                <div class="cbp_tmicon"></div>
                <div class="cbp_tmlabel" data-scroll-reveal="enter right over 1s">
                    <h2>{{ article.title }}</h2>
                    <p><span class="blogpic"><a href="/"><img
                            src="{{ MEDIA_URL }}{{ article.image }}"></a></span>{{ article.desc }}</p>
                    <a href="{% url 'article:detail' %}?id={{ article.id }}" target="_blank" class="readmore">阅读全文&gt;&gt;</a>
                </div>
            </li>
        {% endfor %}

    </ul>
    <div class="page">
        <a title="Total record"><b>{{ page.paginator.num_pages }}</b></a>
        {#        <a href="/news/index_5.html">&lt;&lt;</a></div>#}
            <a href="{% url 'article:show' %}?page={% if page.has_previous %}{{ page.previous_page_number }}{% else %}1{% endif %}&tid={{ tid }}">&lt;</a>
        {% for page_number in  page.paginator.page_range %}
            {% if page.number == page_number %}
                <b>{{ page_number }}</b>
            {% else %}
                <a href="{% url 'article:show' %}?page={{ page_number }}&tid={{ tid }}">{{ page_number }}</a>
            {% endif %}
        {% endfor %}

        <a href="{% url 'article:show' %}?page={% if page.has_next %}{{ page.next_page_number }}{% else %}{{ page.paginator.num_pages }}{% endif %}&tid={{ tid }}">&gt;</a>
        <a href="/news/index_5.html">&gt;&gt;</a>
    </div>

{% endblock %}
|–lmessage.html

{% extends 'base.html' %}
{% load  staticfiles %}
{% block title %}
    留言
{% endblock %}
{% block mycss %}
    <link rel="stylesheet" href="{% static 'css/msg/m.css' %}">
{% endblock %}

{% block content %}

    <div class="leftbox">
        <div class="infos">
            <div class="newsview">
                <h2 class="intitle">您现在的位置是:<a href='/'>首页</a>&nbsp;>&nbsp;留言</h2>
                <div class="gbook">
                    {% for message in page.object_list %}
                        <div class="fb">
                            <ul>
                                <span class="tximg"><img src=" {{ message.icon }}"></span>
                                <p class="fbtime"><span>{{ message.date }}</span> {{ message.nickname }}</p>
                                <p class="fbinfo">{{ message.content }}</p>
                            </ul>
                        </div>
                    {% empty %}
                        <div class="fb">
                            <p>还没有任何留言信息,赶快发表吧....</p>
                        </div>

                    {% endfor %}
                    <div class="page">
                        <a href="{% url 'article:message' %}?page={% if page.has_previous %}{{ page.previous_page_number }}{% else %}1{% endif %}">&lt;</a>
                        {% for page_number in  page.paginator.page_range %}
                            {% if page.number == page_number %}
                              <b>{{ page_number }}</b>
                            {% else %}
                             <a href="{% url 'article:message' %}?page={{ page_number }}">{{ page_number }}</a>
                            {% endif %}
                        {% endfor %}
                        <a href="{% url 'article:message' %}?page={% if page.has_next %}{{ page.next_page_number }}{% else %}{{ page.paginator.num_pages }}{% endif %}">&gt;</a>
                        <a href="/news/index_5.html">&gt;&gt;</a>
                    </div>
                    <div class="gbox">
                        <form action="{% url 'article:message' %}" method="post" name="form1" id="form1">
                            {% csrf_token %}
                            <p><strong>来说点儿什么吧...</strong></p>
                            <p><span> 您的姓名:</span>
                                <input name="name" type="text" id="name"/>
                                *</p>
                            <p><span>选择头像:</span> *</p>
                            <p><i>
                                <input type="radio" value="{% static 'images/tx1.jpg' %}" id="1" name="mycall"
                                       style="display:none">
                                <img id="a" src="{% static 'images/tx1.jpg' %}" onclick="myFun(this.id)"></i> <i>
                                <input type="radio" value="{% static 'images/tx2.jpg' %}" id="2" name="mycall"
                                       style="display:none">
                                <img id="b" src="{% static 'images/tx2.jpg' %}" onclick="myFun(this.id)"></i> <i>
                                <input type="radio" value="{% static 'images/tx3.jpg' %}" id="3" name="mycall"
                                       style="display:none">
                                <img id="c" src="{% static 'images/tx3.jpg' %}" onclick="myFun(this.id)"></i> <i>
                                <input type="radio" value="{% static 'images/tx4.jpg' %}" id="4" name="mycall"
                                       style="display:none">
                                <img id="d" src="{% static 'images/tx4.jpg' %}" onclick="myFun(this.id)"></i> <i>
                                <input type="radio" value="{% static 'images/tx5.jpg' %}" id="5" name="mycall"
                                       style="display:none">
                                <img id="e" src="{% static 'images/tx5.jpg' %}" onclick="myFun(this.id)"></i> <i>
                                <input type="radio" value="{% static 'images/tx6.jpg' %}" id="6" name="mycall"
                                       style="display:none">
                                <img id="f" src="{% static 'images/tx6.jpg' %}" onclick="myFun(this.id)"></i> <i>
                                <input type="radio" value="{% static 'images/tx7.jpg' %}" id="7" name="mycall"
                                       style="display:none">
                                <img id="g" src="{% static 'images/tx7.jpg' %}" onclick="myFun(this.id)"></i> <i>
                                <input type="radio" value="{% static 'images/tx8.jpg' %}" id="8" name="mycall"
                                       style="display:none">
                                <img id="h" src="{% static 'images/tx8.jpg' %}" onclick="myFun(this.id)"></i></p>
                            <p><span class="tnr">留言内容:</span>
                                <textarea name="lytext" cols="60" rows="12" id="lytext"></textarea>
                            </p>
                            <p>
                                <input type="submit" name="Submit3" value="提交"/>
                            </p>
                        </form>
                    </div>
                </div>
                <script>
                    function myFun(sId) {
                        var oImg = document.getElementsByTagName('img');
                        for (var i = 0; i < oImg.length; i++) {
                            if (oImg[i].id == sId) {
                                console.log(oImg[i].previousSibling.previousSibling)
                                oImg[i].previousSibling.previousSibling.checked = true;
                                oImg[i].style.opacity = '1';
                            } else {
                                oImg[i].style.opacity = '.8';
                            }
                        }
                    }
                </script>
            </div>
        </div>
    </div>


{% endblock %}
|–write.html

{% extends 'base.html' %}
{% load staticfiles %}

{% block title %}
    写博客
{% endblock %}
{% block mycss %}
    <style>
       form>p{
           margin: 5px 0;
           font-size: 16px;
       }
    </style>
{% endblock %}
{% block content %}
    <form action="{% url 'article:write' %}" method="post" enctype="multipart/form-data">
        {% csrf_token %}
        {{ form.media }}
        {{ form.as_p }}
        <input type="submit" value="发表文章" class="btn btn-default">

    </form>
{% endblock %}
|–user
|–about.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
    用户注册
{% endblock %}
{% block mycss %}
    <link href="{% static  'css/register.css' %}" rel="stylesheet" type="text/css" media="all"/>
    <!-- css files -->

    <!-- Online-fonts -->
    <link href="//fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&amp;subset=latin-ext,vietnamese"
          rel="stylesheet">
    <!-- //Online-fonts -->
    <link href="{% static 'css/about.css' %}" rel="stylesheet">
{% endblock %}

{% block content %}

    <div class="banner">
      <p data-scroll-reveal="enter top over 2s">我们不停的翻弄着回忆,却再也找不回那时的自己</p>
      <p data-scroll-reveal="enter left over 2s after 1s">人生,是一场盛大的遇见。若你懂得,就请珍惜。</p>
      <p data-scroll-reveal="enter bottom over 2s after 2s">无论下多久的雨,最后都会有彩虹;无论你多么悲伤,要相信幸福在前方等候.</p>
    </div>
    <div class="memorial_day">
      <div class="time_axis"></div>
      <ul>
        <li class="n1"><a href="/">前端入行</a>
          <div class="dateview">2009</div>
        </li>
        <li class="n2"><a href="/">创建个人博客</a>
          <div class="dateview">2011-01-12</div>
        </li>
        <li class="n3"><a href="/">分享第一个博客模板</a>
          <div class="dateview">2013-06-08</div>
        </li>
        <li class="n4"><a href="/">制作第一个html5模板</a>
          <div class="dateview">2013-08-08</div>
        </li>
        <li class="n5"><a href="/">模板更换为时间轴</a>
          <div class="dateview">2017-09-08</div>
        </li>
      </ul>
    </div>
    <div class="about left">
  <h2>Just about me</h2>
    <ul>
     <p>杨青,女,一个80后草根女站长!09年入行。从搬砖一样的生活方式换成了现在有“单”而居的日子。当然这个单不是单身的单,跟我的职业相比,爱情脱单并不是问题!虽然极尽苛刻的征婚条件但也远不及客户千奇百怪的要求。告别了朝九晚五,躲过了风吹日晒,虽然不再有阶梯式的工资,但是偶尔可以给自己放放假,挽着老公,一起轻装旅行。</p>
<p>
人生就是一个得与失的过程,而我却是一个幸运者,得到的永远比失去的多。生活的压力迫使我放弃了轻松的前台接待,放弃了体面的编辑,换来虽有些蓬头垢面的工作,但是我仍然很享受那些熬得只剩下黑眼圈的日子,因为我在学习使用Photoshop、Flash、Dreamweaver、ASP、PHP、JSP...中激发了兴趣,然后越走越远....</p>
<p>在这条路上,我要感谢三个人,第一个是我从事编辑的老板,是他给了我充分学习研究div的时间,第二个人是我的老师,如果不是街上的一次偶遇,如果不是因为我正缺钱,我不会去强迫自己做不会的事情,但是金钱的诱惑实在是抵挡不了,于是我选择了“接招”,东拼西凑的把一个网站做好了,当时还堪称佳作的网站至今已尘归尘土归土了。第三个人,我总说他是我的伯乐,因为我当初应聘技术员的时候,我说我什么都不会,但是他却给了我机会,而我就牢牢的把握了那次机会,直到现在如果不是我主动把域名和空间转出来,我会一直霸占着公司资源,免费下去(可我就偏偏不是喜欢爱占便宜的人,总感觉欠了就得还)...</p>
<p>
还要特别感谢一个人,是我的老公。他是我的百科,我不会的,他会,最后我还是不会。博客能做到今天这样,一半都有他的功劳。他不仅仅支持我的事业作为我有力的经济后盾,还毫无怨言的包容我所有工作、生活当中有理无理的坏脾气,曾经我是多么有自己原则的一个人,但是遇到他,打破了我自己毕生坚持的原则,喜欢一句话“冥冥中该来则来,无处可逃”。
</p>
    </ul>
    <h2>About my blog</h2>
    <p>域  名:www.yangqq.com 创建于2011年01月12日 </p>
    <p>服务器:阿里云服务器<a href="https://promotion.aliyun.com/ntms/act/ambassador/sharetouser.html?userCode=8smrzoqa&amp;productCode=vm" target="_blank" class="blog_link">购买空间</a><a href="/jstt/web/2014-01-18/644.html" target="_blank" class="blog_link">参考我的空间配置</a></p>
    <p>程  序:PHP 帝国CMS7.0</p>


</div>

{% endblock %}

|–center.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
    用户注册
{% endblock %}
{% block mycss %}
    <link href="{% static  'css/register.css' %}" rel="stylesheet" type="text/css" media="all"/>
    <!-- css files -->

    <!-- Online-fonts -->
    <link href="//fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&amp;subset=latin-ext,vietnamese"
          rel="stylesheet">
    <style>
        #icon {
            width: 80px;
            height: 80px;
            border: #4bcfef;
            border-radius: 40px;
        }
    </style>
{% endblock %}

{% block content %}
    <!-- Main Content -->
    <div class="main">
        <div class="main-w3l">
            <h1 class="logo-w3">用户中心</h1>
            <div class="w3layouts-main">
                <h2><span>个人信息</span></h2>
                <p>{{ msg }}</p>
                <form action="{% url 'user:center1' %}" method="post" enctype="multipart/form-data"> {% csrf_token %}
                    <input placeholder="用户名" name="username" value='{{ user.username }}' type="text" required="">
                    <input placeholder="邮箱" name="email" type="email" value='{{ user.email }}' required="">
                    <input placeholder="手机号码" name="mobile" type="text" value='{{ user.mobile }}' required="">
                    <img src="{{ user.yunicon }}" alt="" id="icon">
                    <input type="file" name="icon">
                    <input type="submit" value="提交更新" name="login">
                </form>
            </div>


        </div>
    </div>
{% endblock %}

{% block myjs %}
    <script>
        addEventListener("load", function () {
            setTimeout(hideURLbar, 0);
        }, false);

        function hideURLbar() {
            window.scrollTo(0, 1);
        }
    </script>

    <script>


    </script>
{% endblock %}
|–codelogin.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
    用户登录
{% endblock %}
{% block mycss %}
    <link href="{% static  'css/register.css' %}" rel="stylesheet" type="text/css" media="all"/>
    <!-- css files -->

    <!-- Online-fonts -->
    <link href="//fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&amp;subset=latin-ext,vietnamese"
          rel="stylesheet">
    <!-- //Online-fonts -->
{% endblock %}

{% block content %}
    <div class="main">
        <div class="main-w3l">
            <h1 class="logo-w3">个人博客用户登录</h1>
            <div class="w3layouts-main">
                <h2><span><a href="{% url 'user:login' %}">密码登录</a></span> <span><a href="{% url 'user:codelogin' %}"
                                                                                    style="color: #4bcfef">验证码登录</a></span>
                </h2>
                <p>{{ msg }} {{ errors }}</p>
                <form action="{% url 'user:codelogin' %}" method="post"> {% csrf_token %}
                    <input placeholder="手机号码" name="mobile" type="text" id='mobile' required="">
                    <input placeholder="输入验证码" name="code" type="text">
                    <button id="btn" type="button">发送验证码</button>
                    <input type="submit" value="用户登录" name="login">
                </form>
                <a href="{% url 'user:register' %}"><span>注册新用户?</span></a>
            </div>

        </div>
    </div>
{% endblock %}

{% block myjs %}
    <script>
        $(function () {
            $('#btn').click(function () {
                var mobile = $('#mobile').val();
                if (mobile.length == 11) {
                    $.getJSON('{% url 'user:send_code' %}', {mobile: mobile}, function (data) {
                        console.log(data)
                        if (data.status == 501) {
                            flag = confirm(data.msg + ',是否跳转注册页面进行注册?');
                            if (flag) {
                                window.location.href = '{% url 'user:register' %}'
                            }
                        } else {
                            alert(data.msg)
                        }
                    })
                } else {
                    alert('输入正确的手机号码!')
                }
            });
        });


    </script>
{% endblock %}

|–forget_pwd.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
    用户登录
{% endblock %}
{% block mycss %}
    <link href="{% static  'css/register.css' %}" rel="stylesheet" type="text/css" media="all"/>
    <!-- css files -->

    <!-- Online-fonts -->
    <link href="//fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&amp;subset=latin-ext,vietnamese"
          rel="stylesheet">
    <!-- //Online-fonts -->
{% endblock %}

{% block content %}
    <div class="main">
        <div class="main-w3l">
            <h1 class="logo-w3">忘记密码</h1>

            <div class="w3layouts-main">
                <p>{{ msg }} {{ errors }}</p>
                <form action="{% url 'user:forget_pwd' %}" method="post"> {% csrf_token %}
                    {{ form.email }}
                    {{ form.captcha }}
                    <input type="submit" value="找回密码">
                </form>
            </div>

        </div>
    </div>
{% endblock %}


{% block myjs %}
    <script>
      $(function(){
          // 刷新动作
        $('.captcha').click(function(){
            var img= $(this);
           $.getJSON('/captcha/refresh',function(data){
               console.log(data)
               img.attr('src',data['image_url']);
               $('#id_captcha_0').val(data['key'])
           })
        });

        // 验证验证码是否正确
          $('#id_captcha_1').blur(function(){
              var $this = $(this);
              var key = $('#id_captcha_0').val();
              var code = $(this).val();

              $.getJSON('{% url 'user:valide_code' %}',{key:key,code:code},function(data){
                    console.log(data)
                  
                  if(data.status==1){
                    $this.after('<span>验证码正确</span>')
                  }else{
                    $this.after('<span>验证码错误</span>')
                  }
              })
          })
      });

    </script>
{% endblock %}
|–login.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
    用户登录
{% endblock %}
{% block mycss %}
    <link href="{% static  'css/register.css' %}" rel="stylesheet" type="text/css" media="all"/>
    <!-- css files -->

    <!-- Online-fonts -->
    <link href="//fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&amp;subset=latin-ext,vietnamese"
          rel="stylesheet">
    <!-- //Online-fonts -->
{% endblock %}

{% block content %}
    <div class="main">
        <div class="main-w3l">
            <h1 class="logo-w3">个人博客用户登录</h1>

            <div class="w3layouts-main">
                <h2><span><a href="{% url 'user:login' %}" style="color: #4bcfef">密码登录</a></span> <span><a
                        href="{% url 'user:codelogin' %}">验证码登录</a></span></h2>
                <p>{{ msg }} {{ errors }}</p>
                <form action="{% url 'user:login' %}" method="post"> {% csrf_token %}
                    <input placeholder="用户名" name="username" type="text" required="">
                    <input placeholder="密码" name="password" type="password" id="password1" required="">
                    <input type="submit" value="用户登录" name="login">
                </form>
                <a href="{% url 'user:forget_pwd' %}"><span>忘记密码?</span></a> <a href="{% url 'user:register' %}"><span>注册新用户?</span></a>
            </div>

        </div>
    </div>
{% endblock %}


|–register.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
    用户注册
{% endblock %}
{% block mycss %}
    <link href="{% static  'css/register.css' %}" rel="stylesheet" type="text/css" media="all"/>
    <!-- css files -->

    <!-- Online-fonts -->
    <link href="//fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&amp;subset=latin-ext,vietnamese"
          rel="stylesheet">
    <!-- //Online-fonts -->
{% endblock %}

{% block content %}
    <!-- Main Content -->
    <div class="main">
        <div class="main-w3l">
            <h1 class="logo-w3">个人博客用户注册</h1>
            <div class="w3layouts-main">
                <h2><span>现在注册</span></h2>
                <p>{{ msg }}</p>
                <form action="{% url 'user:register' %}" method="post"> {% csrf_token %}
                    <input placeholder="用户名" name="username" type="text" required="">
                    <input placeholder="邮箱" name="email" type="email" required="">
                    <input placeholder="手机号码" name="mobile" type="text" required="">
                    <input placeholder="密码" name="password" type="password" id="password1" required="">
                    <input placeholder="确认密码" name="password" type="password" id="password2" required="">
                    <input type="submit" value="提交注册" name="login">
                </form>
            </div>


        </div>
    </div>
{% endblock %}

{% block myjs %}
    <script>
        addEventListener("load", function () {
            setTimeout(hideURLbar, 0);
        }, false);

        function hideURLbar() {
            window.scrollTo(0, 1);
        }
    </script>

    <script>

        window.onload = function () {
            document.getElementById("password1").onchange = validatePassword;
            document.getElementById("password2").onchange = validatePassword;
        }

        function validatePassword() {
            var pass2 = document.getElementById("password2").value;
            var pass1 = document.getElementById("password1").value;
            if (pass1 != pass2)
                document.getElementById("password2").setCustomValidity("Passwords Don't Match");
            else
                document.getElementById("password2").setCustomValidity('');
            //empty string means no validation error
        }
    </script>
{% endblock %}
|–update_pwd.html

{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}
    用户登录
{% endblock %}
{% block mycss %}
    <link href="{% static  'css/register.css' %}" rel="stylesheet" type="text/css" media="all"/>
    <!-- css files -->

    <!-- Online-fonts -->
    <link href="//fonts.googleapis.com/css?family=Montserrat:100,100i,200,200i,300,300i,400,400i,500,500i,600,600i,700,700i,800,800i,900,900i&amp;subset=latin-ext,vietnamese"
          rel="stylesheet">
    <!-- //Online-fonts -->
{% endblock %}

{% block content %}
    <div class="main">
        <div class="main-w3l">
            <h1 class="logo-w3">更新密码</h1>

            <div class="w3layouts-main">

                <p>{{ msg }} {{ errors }}</p>
                <form action="{% url 'user:update_pwd' %}" method="post"> {% csrf_token %}
                    <input type="hidden" value="{{ c }}" name="code">
                    <input placeholder="输入新密码" name="password" type="password" required="">
                    <input placeholder="输入确认密码" name="repassword" type="password" required="">
                    <input type="submit" value="更新密码">
                </form>
            </div>

        </div>
    </div>
{% endblock %}


|–zhuce.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册</title>
</head>
<body>
<form action="{% url 'user:zhuce' %}" method="post">{% csrf_token %}
    {{ rform.as_p }}

    <input type="submit" value="注册">
</form>

<form action="{% url 'user:zhuce' %}" method="post">{% csrf_token %}
{#    {{ rform.as_ul }}#}
    {{ rform.username }}
    <input type="submit" value="注册">
</form>
</body>
</html>

article

|–init.py
default_app_config = 'article.apps.ArticleConfig'
|–admin.py
from django.contrib import admin

# Register your models here.
from article.models import Article, Tag

admin.site.register(Article)
admin.site.register(Tag)
|–adminx.py
import xadmin
from article.models import Article, Tag


class ArticleAdmin(object):
    # 页面中显示的列
    list_display = ['title', 'click_num', 'love_num', 'user']
    # 搜索
    search_fields = ['title', 'id']
    # 可编辑的列
    list_editable = ['click_num', 'love_num']
    # 用于过滤
    list_filter = ['date', 'user']


# 注册
xadmin.site.register(Article, ArticleAdmin)
xadmin.site.register(Tag)

|–apps.py
from django.apps import AppConfig


class ArticleConfig(AppConfig):
    name = 'article'
    verbose_name = '文章操作'

|–forms.py
from django import forms

from article.models import Article


class ArticleForm(forms.ModelForm):
    class Meta:
        model = Article
        fields = '__all__'
        exclude = ['click_num', 'love_num','user']

|–models.py
from ckeditor.fields import RichTextField
from ckeditor_uploader.fields import RichTextUploadingField
from django.db import models

# Create your models here.
# title desc  content    date   click_num    image  love_num    author  tags
from user.models import UserProfile


class Tag(models.Model):
    name = models.CharField(max_length=50, verbose_name='标签名')

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'tag'
        verbose_name = '标签表'
        verbose_name_plural = verbose_name


class Article(models.Model):
    title = models.CharField(max_length=100, verbose_name='标题')
    desc = models.CharField(max_length=256, verbose_name='简介')
    content = RichTextUploadingField(verbose_name='内容')
    date = models.DateField(auto_now=True, verbose_name='发表日期')
    click_num = models.IntegerField(default=0, verbose_name='点击量')
    love_num = models.IntegerField(default=0, verbose_name='点赞量')
    image = models.ImageField(upload_to='uploads/article/%Y/%m/%d', verbose_name='文章图片',
                              default='uploads/article/2019/05/10/photos2.jpg')

    tags = models.ManyToManyField(to=Tag, verbose_name='标签')
    user = models.ForeignKey(to=UserProfile, on_delete=models.CASCADE, verbose_name='作者')

    def __str__(self):
        return self.title

    class Meta:
        db_table = 'article'
        verbose_name = '文章表'
        verbose_name_plural = verbose_name


# nickname  date  content
class Comment(models.Model):
    nickname = models.CharField(max_length=50, verbose_name='昵称')
    content = models.TextField(verbose_name='内容')
    date = models.DateTimeField(auto_now=True, verbose_name='评论时间')

    article = models.ForeignKey(to=Article, on_delete=models.CASCADE, verbose_name='文章')

    def __str__(self):
        return self.nickname

    class Meta:
        db_table = 'comment'
        verbose_name = '评论表'
        verbose_name_plural = verbose_name


# 留言model
class Message(models.Model):
    nickname = models.CharField(max_length=50, verbose_name='昵称')
    content = models.TextField(verbose_name='内容')
    icon =models.CharField(max_length=150,verbose_name='头像',default='images/tx1.jpg')
    date = models.DateTimeField(auto_now=True, verbose_name='留言时间')

    def __str__(self):
        return self.nickname

    class Meta:
        db_table = 'message'
        verbose_name = '留言表'
        verbose_name_plural = verbose_name

|–tests.py
|–urls.py
from django.urls import path

from article.views import *

app_name = 'article'

urlpatterns = [
    path('detail', article_detail, name='detail'),
    path('show', article_show, name='show'),
    path('write', write_article, name='write'),
    path('comment', article_comment, name='comment'),
    path('message', blog_message, name='message')
]

|–views.py
from django.contrib.auth.decorators import login_required
from django.core.checks import Tags
from django.core.paginator import Paginator
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect

# Create your views here.
from django.urls import reverse

from article.forms import ArticleForm
from article.models import Article, Tag, Comment, Message


# 文章详情
def article_detail(request):
    id = request.GET.get('id')
    article = Article.objects.get(pk=id)
    article.click_num += 1
    article.save()
    # 查询相关文章
    tags_list = article.tags.all()  # 添加()
    list_about = []  # 存放文章的列表
    for tag in tags_list:
        for article1 in tag.article_set.all():
            if article1 not in list_about and len(list_about) < 6:
                list_about.append(article1)

    # 查询评论数
    comments = Comment.objects.filter(article_id=id)

    return render(request, 'article/info.html',
                  context={'article': article, 'list_about': list_about, 'comments': comments})


# 学无止境
def article_show(request):
    tags = Tag.objects.all()[:6]
    tid = request.GET.get('tid', "")  # None
    if tid:
        tag = Tag.objects.get(pk=tid)
        # articles = tag.article_set.all()
        articles = Article.objects.filter(tags__name=tag.name)
    else:
        articles = Article.objects.all()

    paginator = Paginator(articles, 3)  # Paginator(对象列表,每页几条记录)
    print(paginator.count)  # 总的条目数  总的记录数
    print(paginator.num_pages)  # 可以分页的数量  总的页码数
    print(paginator.page_range)  # 页面的范围

    # 方法: get_page()
    page_number = request.GET.get('page', 1)
    print(page_number)
    page = paginator.get_page(page_number)  # 返回的是page对象
    print('--->', page_number, page.number)
    # page.has_next()  # 有没有下一页
    # page.has_previous()  # 判断是否存在前一页
    # page.next_page_number() # 获取下一页的页码数
    # page.previous_page_number() # 获取前一页的页码数

    # 属性:
    # object_list   当前页的所有对象
    #  number       当前的页码数
    # paginator     分页器对象

    return render(request, 'article/learn.html', context={'page': page, 'tags': tags, 'tid': tid})


# 写博客
@login_required
def write_article(request):
    if request.method == 'GET':
        aform = ArticleForm()
        return render(request, 'article/write.html', context={'form': aform})
    else:
        aform = ArticleForm(request.POST, request.FILES)
        if aform.is_valid():
            data = aform.cleaned_data
            article = Article()
            article.title = data.get('title')
            article.desc = data.get('desc')
            article.content = data.get('content')
            print(type(data.get('image')))

            article.image = data.get('image')
            article.desc = data.get('desc')
            article.user = request.user  # 1对多 直接赋值
            article.save()

            # 多对多 必须添加到文章保存的后面添加
            article.tags.set(data.get('tags'))
            return redirect(reverse('index'))

        return render(request, 'article/write.html', context={'form': aform})


# 文章评论
def article_comment(request):
    # 直接接受
    nickname = request.GET.get('nickname')
    content = request.GET.get('saytext')
    aid = request.GET.get('aid')

    comment = Comment.objects.create(nickname=nickname, content=content, article_id=aid)

    if comment:
        data = {'status': 1}
    else:
        data = {'status': 0}
    return JsonResponse(data)


# 留言
def blog_message(request):
    messages = Message.objects.all()
    paginator = Paginator(messages, 8)
    # 获取页码数
    page = request.GET.get('page', 1)
    # 得到page对象
    page = paginator.get_page(page)

    if request.method == 'GET':
        return render(request, 'article/lmessage.html', context={'page':page})
    else:
        name = request.POST.get('name')
        mycall = request.POST.get('mycall')
        lytext = request.POST.get('lytext')
        if name and lytext:
            message = Message.objects.create(nickname=name, icon=mycall, content=lytext)
            if message:
                return redirect(reverse('article:message'))
        return render(request, 'article/lmessage.html', context={'page':page, 'error': '必须输入用户名和内容'})

|–migrations

user

|–init.py
|–admin.py
from django.contrib import admin

# Register your models here.
from user.models import UserProfile

admin.site.register(UserProfile)

|–adminx.py
import xadmin
from article.models import Article, Tag
from user.models import UserProfile

# xadmin.site.register(UserProfile)
from xadmin import views


class BaseSettings(object):
    enable_themes = True
    use_bootswatch = True


class GlobalSettings(object):
    site_title = '博客后台管理'
    site_footer = '达达的博客公司'

# 注册
xadmin.site.register(views.BaseAdminView, BaseSettings)
xadmin.site.register(views.CommAdminView, GlobalSettings)

|–apps.py
from django.apps import AppConfig


class UserConfig(AppConfig):
    name = 'user'
    verbose_name = '用户操作'

|–forms.py
import re

from captcha.fields import CaptchaField
from django.core.exceptions import ValidationError
from django.forms import Form, ModelForm, EmailField
from django import forms

from user.models import UserProfile


class UserRegisterForm(Form):
    username = forms.CharField(max_length=50, min_length=6, error_messages={'min_length': '用户名长度至少6位', }, label='用户名')
    email = forms.EmailField(required=True, error_messages={'required': '必须填写邮箱信息'}, label='邮箱')
    mobile = forms.CharField(required=True, error_messages={'required': '必须填写手机号码'}, label='手机')
    password = forms.CharField(required=True, error_messages={'required': '必须填写密码'}, label='密码',
                               widget=forms.widgets.PasswordInput)

    # repassword = forms.CharField(required=True, error_messages={'required': '必须填写确认密码'}, label='密码',
    #                              widget=forms.widgets.PasswordInput)
    # favorite_colors = forms.MultipleChoiceField(
    #     required=False,
    #     widget=forms.CheckboxSelectMultiple,
    #     choices=(('blue', 'Blue'), ('red', 'Red'), ('green', 'Green'), ('yellow', 'Yellow')), label='最喜欢的颜色'
    # )

    def clean_username(self):
        username = self.cleaned_data.get('username')
        result = re.match(r'[a-zA-Z]\w{5,}', username)
        if not result:
            raise ValidationError('用户名必须字母开头')
        return username


class RegisterForm(ModelForm):
    # repassword = forms.CharField(required=True, error_messages={'required': '必须填写确认密码'}, label='确认密码',
    #                                           widget=forms.widgets.PasswordInput)

    class Meta:
        model = UserProfile
        fields = ['username', 'email', 'mobile', 'password']
        # fields = '__all__'
        # exclude = ['first_name','date_joined','last_name']

    def clean_username(self):
        username = self.cleaned_data.get('username')
        result = re.match(r'[a-zA-Z]\w{5,}', username)
        if not result:
            raise ValidationError('用户名必须字母开头')
        return username


class LoginForm(Form):
    username = forms.CharField(max_length=50, min_length=6, error_messages={'min_length': '用户名长度至少6位', }, label='用户名')
    password = forms.CharField(required=True, error_messages={'required': '必须填写密码'}, label='密码',
                               widget=forms.widgets.PasswordInput)

    # class Meta:
    #     model = UserProfile
    #     fields = ['username', 'password']

    def clean_username(self):
        username = self.cleaned_data.get('username')
        if not UserProfile.objects.filter(username=username).exists():
            raise ValidationError('用户名不存在')
        return username


# 验证码captcha的Form
class CaptchaTestForm(forms.Form):
    email = EmailField(required=True, error_messages={'required': '必须填写邮箱'},label='邮箱')
    captcha = CaptchaField()

|–models.py
from django.contrib.auth.models import AbstractUser
from django.db import models


# Create your models here.

class UserProfile(AbstractUser):
    mobile = models.CharField(max_length=11, verbose_name='手机号码', unique=True)
    # icon = models.ImageField(upload_to='uploads/%Y/%m/%d', default="uploads/mine1.png")
    yunicon = models.CharField(max_length=200, default='')

    class Meta:
        db_table = 'userprofile'
        verbose_name = '用户表'
        verbose_name_plural = verbose_name

|–tests.py
|–urls.py
from django.urls import path
from user.views import *

app_name = 'user'

urlpatterns = [
    path('register', user_register, name='register'),
    path('login', user_login, name='login'),
    path('codelogin', code_login, name='codelogin'),
    path('send_code', send_code, name='send_code'),
    path('logout', user_logout, name='logout'),
    path('forget_pwd', forget_password, name='forget_pwd'),
    path('valide_code', valide_code, name='valide_code'),
    path('update_pwd', update_pwd, name='update_pwd'),
    path('center', user_center, name='center'),  # 本地存储
    path('center1', user_center1, name='center1'),  # 云存储
    path('test',test,name='test'),
    path('zhuce', user_zhuce, name='zhuce')

]

|–utils.py
# 作用就是向网易云信发送请求,帮助后台发送短信息给客户
import hashlib
import json
import os
import uuid
from time import time

import requests
from django.core.mail import send_mail
from qiniu import Auth, put_file, put_data

from djangoday4.settings import EMAIL_HOST_USER, MEDIA_ROOT
from user.models import UserProfile


# 发送短信息
def util_sendmsg(mobile):
    url = 'https://api.netease.im/sms/sendcode.action'
    data = {'mobile': mobile}
    # 4部分组成 headers: AppKey  Nonce  CurTime  CheckSum
    AppKey = '1bdcdeda105c1d91e802a191d8f5ed94'
    Nonce = '843hjfd87fdfshdjfhs5433'
    CurTime = str(time())
    AppSecret = '05bf2ece7293'
    content = AppSecret + Nonce + CurTime
    CheckSum = hashlib.sha1(content.encode('utf-8')).hexdigest()

    headers = {'AppKey': AppKey, 'Nonce': Nonce, 'CurTime': CurTime, 'CheckSum': CheckSum}

    response = requests.post(url, data, headers=headers)
    # json
    str_result = response.text  # 获取响应体

    json_result = json.loads(str_result)  # 转成json

    return json_result


# 发送邮件
def send_email(email, request):
    subject = '个人博客找回密码'
    user = UserProfile.objects.filter(email=email).first()
    ran_code = uuid.uuid4()
    print(ran_code)
    print(type(ran_code))
    ran_code = str(ran_code)
    print(type(ran_code))
    ran_code = ran_code.replace('-', '')
    request.session[ran_code] = user.id
    message = '''
     可爱的用户:
            <br>
            您好!此链接用户找回密码,请点击链接: <a href='http://127.0.0.1:8000/user/update_pwd?c=%s'>更新密码</a>,
            <br>
            如果链接不能点击,请复制:<br>
            http://127.0.0.1:8000/user/update_pwd?c=%s
        
           个人博客团队
    ''' % (ran_code, ran_code)
    # 发送邮件send_mail
    result = send_mail(subject, "", EMAIL_HOST_USER, [email, ], html_message=message)
    return result


# 上传图片到七牛云
def upload_image(storeobj):
    access_key = '1fXvG9wkbN7AgRUG6usHDcRP5Bb85apcovRAIITP'
    secret_key = 'Aqf1lPAmUG72EdZJ7PxKtWHfWDYNdUycZP1TaAIN'

    # 构建鉴权对象
    q = Auth(access_key, secret_key)

    # 要上传的空间
    bucket_name = 'myblog'

    # 上传后保存的文件名
    key = storeobj.name

    # 生成上传 Token,可以指定过期时间等
    token = q.upload_token(bucket_name, key, 3600)

    # 要上传文件的本地路径
    # localfile = os.path.join(MEDIA_ROOT, imagepath)  # 本地图片
    ret, info = put_data(token, key, storeobj.read())

    print(ret, info)
    filename = ret.get('key')
    save_path = 'http://pr67kkhq9.bkt.clouddn.com/'+filename
    return save_path

|–views.py
from captcha.models import CaptchaStore
from django.contrib.auth import logout, login, authenticate
from django.contrib.auth.decorators import login_required
from django.contrib.auth.hashers import make_password, check_password
# from django.contrib.auth.views import logout
from django.core.mail import send_mail
from django.db.models import Q
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
from django.middleware.security import SecurityMiddleware
from django.middleware.csrf import CsrfViewMiddleware
# Create your views here.
from django.urls import reverse

from article.models import Article
from user.forms import UserRegisterForm, RegisterForm, LoginForm, CaptchaTestForm
from user.models import UserProfile
from user.utils import util_sendmsg, send_email, upload_image


def index(request):
    farticles = Article.objects.all().order_by('-click_num')
    darticles = Article.objects.all().order_by('-date')[:8]
    return render(request, 'index.html', context={'figure_articles': farticles[:3], 'darticles': darticles})


# 注册
def user_register(request):
    if request.method == 'GET':
        return render(request, 'user/register.html')
    else:
        rform = RegisterForm(request.POST)  # 使用form获取数据
        if rform.is_valid():  # 进行数据的校验
            # 从干净的数据中取值
            username = rform.cleaned_data.get('username')
            email = rform.cleaned_data.get('email')
            mobile = rform.cleaned_data.get('mobile')
            password = rform.cleaned_data.get('password')
            if not UserProfile.objects.filter(Q(username=username) | Q(mobile=mobile)).exists():
                # 注册到数据库中
                password = make_password(password)  # 密码加密
                user = UserProfile.objects.create(username=username, password=password, email=email, mobile=mobile)
                if user:
                    return HttpResponse('注册成功')
            else:
                return render(request, 'user/register.html', context={'msg': '用户名或者手机号码已经存在!'})
        return render(request, 'user/register.html', context={'msg': '注册失败,重新填写!'})


# 用户登录
def user_login(request):
    if request.method == 'GET':
        return render(request, 'user/login.html')
    else:
        lform = LoginForm(request.POST)
        if lform.is_valid():
            username = lform.cleaned_data.get('username')
            password = lform.cleaned_data.get('password')
            # 进行数据库的查询
            # user = UserProfile.objects.filter(username=username).first()
            # flag = check_password(password, user.password)
            # if flag:
            #     # 保存session信息
            #     request.session['username'] = username

            # 方式二前提是继承了AbstractUser
            user = authenticate(username=username, password=password)
            if user:
                login(request, user)  # 将用户对象保存在底层的request中  (session)

                return redirect(reverse('index'))
        return render(request, 'user/login.html', context={'errors': lform.errors})


# 用户注销
def user_logout(request):
    # request.session.clear()  # 删除字典
    # request.session.flush()  # 删除django_session + cookie +字典
    logout(request)

    return redirect(reverse('index'))


# 手机验证码登录
def code_login(request):
    if request.method == 'GET':
        return render(request, 'user/codelogin.html')
    else:
        mobile = request.POST.get('mobile')
        code = request.POST.get('code')

        # 根据mobile去session中取值
        check_code = request.session.get(mobile)
        if code == check_code:
            user = UserProfile.objects.filter(mobile=mobile).first()
            # user = authenticate(username=user.username, password=user.password)
            print(user)
            if user:
                login(request, user)
                return redirect(reverse('index'))
            else:
                return HttpResponse('验证失败!')
        else:
            return render(request, 'user/codelogin.html', context={'msg': '验证码有误!'})


# 发送验证码路由  ajax发过来的请求
def send_code(request):
    mobile = request.GET.get('mobile')
    data = {}
    if UserProfile.objects.filter(mobile=mobile).exists():
        # 发送验证码  第三方
        json_result = util_sendmsg(mobile)
        # 取值:
        status = json_result.get('code')
        if status == 200:
            check_code = json_result.get('obj')
            # 使用session保存
            request.session[mobile] = check_code

            data['status'] = 200
            data['msg'] = '验证码发送成功'
        else:
            data['status'] = 500
            data['msg'] = '验证码发送失败'
    else:
        data['status'] = 501
        data['msg'] = '用户不存在'

    return JsonResponse(data)


# 忘记密码
def forget_password(request):
    if request.method == 'GET':
        form = CaptchaTestForm()
        return render(request, 'user/forget_pwd.html', context={'form': form})
    else:
        # 获取提交的邮箱,发送邮件,通过发送的邮箱链接设置新的密码
        email = request.POST.get('email')
        # 给此邮箱地址发送邮件
        result = send_email(email, request)
        if result:
            return HttpResponse("邮件发送成功!赶快去邮箱更改密码!<a href='/'>返回首页>>> </a>")


# 更新密码
def update_pwd(request):
    if request.method == 'GET':
        c = request.GET.get('c')
        return render(request, 'user/update_pwd.html', context={'c': c})
    else:
        code = request.POST.get('code')
        uid = request.session.get(code)
        user = UserProfile.objects.get(pk=uid)
        # 获取密码
        pwd = request.POST.get('password')
        repwd = request.POST.get('repassword')
        if pwd == repwd and user:
            pwd = make_password(pwd)
            user.password = pwd
            user.save()
            return render(request, 'user/update_pwd.html', context={'msg': '用户密码更新成功!'})
        else:
            return render(request, 'user/update_pwd.html', context={'msg': '更新失败!'})


# 定义一个路由验证验证码
def valide_code(request):
    if request.is_ajax():
        key = request.GET.get('key')
        code = request.GET.get('code')

        captche = CaptchaStore.objects.filter(hashkey=key).first()
        if captche.response == code.lower():
            # 正确
            data = {'status': 1}
        else:
            # 错误的
            data = {'status': 0}
        return JsonResponse(data)


# 用户的个人中心  login(request,user)   user--->继承自abstractuser
@login_required
def user_center(request):
    user = request.user
    if request.method == 'GET':

        return render(request, 'user/center.html', context={'user': user})
    else:
        username = request.POST.get('username')
        email = request.POST.get('email')
        mobile = request.POST.get('mobile')
        icon = request.FILES.get('icon')
        # print(type(icon))
        # print(icon.name)
        # print(icon.read())
        # 更新用户
        user.username = username
        user.email = email
        user.mobile = mobile
        user.icon = icon  # ImageField(upload_to='')
        user.save()

        return render(request, 'user/center.html', context={'user': user})


@login_required
def user_center1(request):
    user = request.user
    if request.method == 'GET':

        return render(request, 'user/center.html', context={'user': user})
    else:
        username = request.POST.get('username')
        email = request.POST.get('email')
        mobile = request.POST.get('mobile')
        icon = request.FILES.get('icon')  # 内存存储对象

        user.username = username
        user.email = email
        user.mobile = mobile

        # print(str(user.icon),type(user.icon))
        # 上传图片到七牛云
        save_path = upload_image(icon)
        user.yunicon = save_path
        user.save()

        return render(request, 'user/center.html', context={'user': user})


# from  django.db.models.fields.files import ImageFieldFile

def test(request):
    return render(request, 'article/info.html')


def user_zhuce(request):
    if request.method == 'GET':
        rform = RegisterForm()
        return render(request, 'user/zhuce.html', context={'rform': rform})
    else:
        rform = UserRegisterForm(request.POST)
        if rform.is_valid():
            print(rform.cleaned_data)
            username = rform.cleaned_data.get('username')
            email = rform.cleaned_data.get('email')
            mobile = rform.cleaned_data.get('mobile')
            password = rform.cleaned_data.get('password')

            # 数据库中注册
        return HttpResponse('yiui')

|–migrations

xadmin

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值