#第16篇分享:python网站开发-Django源码及视频分享

#Django的源码及视频分享,确实没有啥捷径,自己也学了好几周:

1.源码地址:( 本人学习过程手打的代码,以及最终完成的一个blog项目(只做了部分功能)):Django源码

2.视频网址: Django的基础操作:Django美女老师教学视频
blog系统的搭建:耐心看完,还是不错滴
视频讲的还是不错的,知识这个东西就是会了不难,难了不会;重在坚持,现在主要是缺少一些项目经历,等我真正走上正轨,一定要多搞搞一些大的项目分享一下,不忘初心,保持善良。

3.一个博客系统的搭建:
a.如果我们不想和其他项目冲突,我们可以建立一个虚拟的环境:
①.首先我们要安装创建虚拟空间的模块virtualenv:
在这里插入图片描述
②.创建一个虚拟空间(virtualenv +虚拟空间的路径):
在这里插入图片描述
③.激活虚拟空间(盘符前面出现环境的名字就是激活成功了):
在这里插入图片描述
在这里插入图片描述
④.激活空间后我们就可以正常使用,例如:安装模块,新建工程:
安装模块:
在这里插入图片描述
下面都是虚拟环境中安装的模块:
在这里插入图片描述
pycharm里面选择虚拟环境的路径:
在这里插入图片描述在这里插入图片描述
新建工程:我们blog项目举例:

为了规整,新建文件夹:D:\Webprojects\blog
在这里插入图片描述
激活django,切换路径cd:D:\Webprojects\blog,创建项目:
执行: django-admin startproject blog
在这里插入图片描述
工程文件夹里面的文件:
在这里插入图片描述
创建app:
执行:确定现在处于 manage.py 所在的目录下(manage.py是创建工程时自动生成的管理文件):
执行命令创建应用: python manage.py startapp app1(app创建完成后,一个简单的django框架就搭建完毕了,之后需要什么文件夹中新建即可)
在这里插入图片描述
查看app1的文件夹:
在这里插入图片描述
注:
admin.py 文件跟网站的后台管理站点配置相关。
apps.py 文件用于配置当前子应用的相关信息。
migrations 目录用于存放数据库迁移历史文件。
models.py 文件用户保存数据库模型类。
tests.py 文件用于开发测试用例,编写单元测试。
views.py 文件用于编写Web应用视图。

后期会新增的文件夹,展示一下,初学先不着急:
在这里插入图片描述
文件夹中查看blog项目全部文件:
在这里插入图片描述
在这里插入图片描述
框架搭建完毕就可以运行工程了:
还是先激活环境,切换到 manage.py所在的文件夹:
执行:python manage.py runserver;如果运行路径不在manage.py下面,注意加上绝对路径即可;

b.blog项目效果及代码展示:可能不是很全面,帮助构建个整体的思维框架,细节可以看看视频:讲真的搭建blog虽然不难,对于初学者也是需要一段时间的;
在这里插入图片描述

Django开发网站的思路:

①.首先了解一下写代码的关系(如下图):
我们工程及app创建完毕之后,我们直接拖拽我们的文件夹到我们的pycharm上就可以像我这样全部打开,打开之后我们需要依次设置一下这几个文件,没有的文件和文件夹右键创建进去就能用:
在这里插入图片描述
代码书写及执行步骤:先去settings.py进行网站的设置,包括数据库连接,app1和工程连接,一些全局变量等->然后要去工程路径下的urls.py创建我们访问时候的网址路径(path(‘app1/’,include(‘app1.urls’))加入这个就和app下面那个urls.py建立了联系)->为了网站更加清晰我们可以在app的文件夹下面再创建一个urls(当我们项目下面有多个app的时候就能感觉到这样设置的优势了)—>每个urls都会指向一个views函数,views函数可以设置渲染一个网页(静态网页就不需要变量,动态的还要和models.py以及forms.py进行交互,是存储变量和表单的模块)—>模板index.html被调用后,就显示出来了,而模板里面可以设置超链接,点击之后可以去urls.py中查找(先去blog下面的,然后是app下面的,找不到报错,找到了就继续调用views.py中的函数,进行页面渲染调用模板)

②.settings.py模块,就是一个配置模块(刚开始不用考虑太多,只需要配置一下数据库,添加app1到"INSTALLED_APPS"里面,和app1建立联系):

"""
Django settings for blog project.

Generated by 'django-admin startproject' using Django 3.0.7.

For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""


import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'xft^y8z8nitw1t7m9w44w)fnj3+g!j-&$qeas#8%xbr@n*pma@'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = ['*']


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app1'
]

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',
]

ROOT_URLCONF = 'blog.urls'

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',
                'app1.views.global_setting',
            ],
        },
    },
]

WSGI_APPLICATION = 'blog.wsgi.application'


# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases

# 数据库的配置
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'blogdb',
        'USER': 'root',
        'PASSWORD': 'f199506',
        'HOST': '',
        'PORT': '',
    }
}


# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators

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',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR,'static\images'),
    os.path.join(BASE_DIR,'static\css'),
    os.path.join(BASE_DIR,'static\js'),
    os.path.join(BASE_DIR,'static'),
]

MEDIA_URL = '/uploads/'
MEDIA_ROOT = os.path.join(BASE_DIR,'uploads').replace('\\','/')

#自定义用户model
AUTH_USER_MODEL = 'app1.User'

#网站的基本信息配置:全局上下文的应用
SIIE_NAME = '天甜费的个人博客'
SIIE_DESC = '专注python开发,欢迎和大家交流'

CSDN = 'https://blog.csdn.net/weixin_46008828'    #关注我


# 自定义日志输出信息
LOGGING = {
    'version': 1,
    'disable_existing_loggers': True,
    'formatters': {
        'standard': {
            'format': '%(asctime)s [%(threadName)s:%(thread)d] [%(name)s:%(lineno)d] [%(module)s:%(funcName)s] [%(levelname)s]- %(message)s'}  #日志格式
    },
    'filters': {
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'class': 'django.utils.log.AdminEmailHandler',
            'include_html': True,
            },
        'default': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'log/all.log',     #日志输出文件
            'maxBytes': 1024*1024*5,                  #文件大小
            'backupCount': 5,                         #备份份数
            'formatter':'standard',                   #使用哪种formatters日志格式
        },
        'error': {
            'level':'ERROR',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'log/error.log',
            'maxBytes':1024*1024*5,
            'backupCount': 5,
            'formatter':'standard',
            },
        'console':{
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'standard'
        },
        'request_handler': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename': 'log/script.log',
            'maxBytes': 1024*1024*5,
            'backupCount': 5,
            'formatter':'standard',
            },
        'scprits_handler': {
            'level':'DEBUG',
            'class':'logging.handlers.RotatingFileHandler',
            'filename':'log/script.log',
            'maxBytes': 1024*1024*5,
            'backupCount': 5,
            'formatter':'standard',
            }
    },
    'loggers': {
        'django': {
            'handlers': ['default', 'console'],
            'level': 'DEBUG',
            'propagate': False
        },
        'django.request': {
            'handlers': ['request_handler'],
            'level': 'DEBUG',
            'propagate': False,
            },
        'scripts': {
            'handlers': ['scprits_handler'],
            'level': 'INFO',
            'propagate': False
        },
        'blog.views': {
            'handlers': ['default', 'error'],
            'level': 'DEBUG',
            'propagate': True
        },
    }
}

③.blog\urls.py & app1\urls.py模块(这是一个路由设置的地方,就相当于指挥作战,我这里给个方向,views.py就得给我执行):
通过加入模块导入实现各个模块间的联系,通过path或者repath(可以输入正则表达式)进行程序的跳转:

"""blog URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/3.0/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,include,re_path
from blog import  settings
#上传图片
from app1.upload import upload_image
from django.views import static



urlpatterns = [

    path('admin/', admin.site.urls),
    path('app1/',include('app1.urls')),

    #其他位置上传照片处理
    re_path(r'uploads/(?P<path>.*)', static.serve, {"document_root": settings.MEDIA_ROOT}),

    #富文本编辑器上传照片问题
    re_path(r'admin/upload/(?P<dir_name>[^/]+)', upload_image, name='upload_image')
]

这个就相当于前线指挥官,直接调动我们的士兵:

from django.urls import path
from app1 import views as app1_view

urlpatterns = [
    #首页展示
    path('index/',app1_view.index),

    # 文章归档url
    path('archive/', app1_view.archive),

    # 文章详情页面
    path('article/', app1_view.article),

# 文章详情页面
    path('login/', app1_view.do_login),

# 文章详情页面
    path('reg/', app1_view.do_reg),

# 文章详情页面
    path('logout/', app1_view.do_logout),

# 文章详情页面
    path('comment_post/', app1_view.comment_post),
]

④.views.py模块(一个功能实现模块,有了它我们的网页才是有了和大众见面的机会,没有士兵的勇猛作战,怎么实现新中国的解放):
代码都是一点点写的,后期又经过了优化,长时间不看也需要缕一缕,我这里只是介绍一个框架和学习思路,后面有机会会更新一些细节上的东西,不要急躁,沉下心学习,没有捷径就是打打打:

from django.shortcuts import render,redirect
import logging
from django.conf import settings
from app1.models import *
#文章分页处理
from django.core.paginator import Paginator,InvalidPage,EmptyPage,PageNotAnInteger

from django.db.models import Count

from app1.forms import *

from django.contrib.auth.views import login, logout
from django.contrib.auth.hashers import make_password, check_password
from django.contrib.auth import authenticate
# Create your views here.

#1.1首网页展示
def index(request):
    try:
        # #1.分类信息的获取(导航栏数据)
        # category_list = Category.objects.all()
        # #2.广告数据(学生自己完成)
        # ad_list = Ad.objects.all()

        #3.最新文章数据
        article_list = Article.objects.all()
        # 分页代码设置
        article_list = paginator_list(request, article_list)

        # # 文章归档操作:(自定义objects 进行数据筛选)
        # archive_list = Article.objects.distinct_date()

    except Exception as e:
        logger.error(e)

    # return render(request,'index.html',{'category_list':category_list,'article_list':article_list,'ad_list':ad_list,})
    return render(request,'index.html',locals())


#1.2 文章归档页面编写
def archive(request):
    try:
        # # 1.分类信息的获取(导航栏数据)
        # category_list = Category.objects.all()
        # # 2.广告数据(学生自己完成)
        # ad_list = Ad.objects.all()
        # 3.归档文章数据
        #先提取客户端提交的信息

        year = request.GET.get('year',None)
        month = request.GET.get('month',None)
        article_list = Article.objects.filter(date_publish__icontains = year+'-'+month)

        #分页代码设置
        article_list = paginator_list(request,article_list)

        # # 文章归档操作:(自定义objects 进行数据筛选)
        # archive_list = Article.objects.distinct_date()
    except Exception as e:
        logger.error(e)
    return render(request, 'archive.html', locals())


#2.日志器的使用
logger = logging.getLogger('blog.views')


#3.全局上下文的使用:变量
def global_setting(request):
    SIIE_NAME = settings.SIIE_NAME
    SIIE_DESC = settings.SIIE_DESC
    CSDN = settings.CSDN
    # 1.分类信息的获取(导航栏数据)
    category_list = Category.objects.all()
    # 2.广告数据(学生自己完成)
    ad_list = Ad.objects.all()
    #3.标签云数据

    #4.文章归档
    # 文章归档操作:(自定义objects 进行数据筛选)
    archive_list = Article.objects.distinct_date()

    #5.友情链接数据


    #6.文章排行榜数据-评论排行
    comment_count_list = Comment.objects.values('article').annotate(comment_count = Count('article')).order_by('-comment_count')   #分组聚合查询
    article_comment_list = [Article.objects.get(pk = comment['article']) for comment in comment_count_list]  #pk是主键的意思

    #----浏览排行
    click_count_list = Article.objects.order_by('-click_count')
    #----站长推荐-按评论
####################################

    return locals()


        # {'SIIE_NAME':settings.SIIE_NAME,
        #    'SIIE_DESC':settings.SIIE_DESC,
        #    'category_list':category_list,
        #    'ad_list':ad_list,
        #     'archive_list':archive_list,
        #    # 'MEDIA_ROOT':settings.MEDIA_ROOT,
        #    # 'MEDIA_URL':settings.MEDIA_URL,
        #    }
#4.分页函数
def paginator_list(request,article_list):
    paginator = Paginator(article_list, 2)
    try:
        # 获取当前页码
        page = int(request.GET.get('page', 1))
        article_list = paginator.page(page)
    except (EmptyPage, InvalidPage, PageNotAnInteger):
        article_list = paginator.page(1)

    return article_list

#5.文章详情
def article(request):
    try:
        #获取文章id
        id = request.GET.get('id',None)

        try:
            #获取文章信息
            article = Article.objects.get(pk = id)

            # 阅读量 +1
            # a = article.objects.create(click_count = (article.click_count+1))     #说啥都不好用,之后成为大神后回来瞅瞅为啥嘞
            # a.save()

            # 阅读量 +1
            article.click_count1()         #竟然搞定了

        except Article.DoesNotExist:
            return render(request,'failure.html',{'reason':'没有找到对应文章'})

    #评论表单
        comment_form = CommentForm({'author': request.user.username,
                                    'email': request.user.email,
                                    'url': request.user.url,
                                    'article': id} if request.user.is_authenticated() else{'article': id})
         # 获取评论信息
        comments = Comment.objects.filter(article=article).order_by('id')
        comment_list = []
        for comment in comments:
            for item in comment_list:
                if not hasattr(item, 'children_comment'):
                    setattr(item, 'children_comment', [])
                if comment.pid == item:
                    item.children_comment.append(comment)
                    break
            if comment.pid is None:
                comment_list.append(comment)

    except Exception as e:
        logger.error(e)

    return render(request, 'article.html', locals())

# 提交评论
def comment_post(request):
    try:
        comment_form = CommentForm(request.POST)
        if comment_form.is_valid():
            #获取表单信息
            comment = Comment.objects.create(username=comment_form.cleaned_data["author"],
                                             email=comment_form.cleaned_data["email"],
                                             url=comment_form.cleaned_data["url"],
                                             content=comment_form.cleaned_data["comment"],
                                             article_id=comment_form.cleaned_data["article"],
                                             user=request.user if request.user.is_authenticated() else None)
            comment.save()
        else:
            return render(request, 'failure.html', {'reason': comment_form.errors})
    except Exception as e:
        logger.error(e)
    return redirect(request.META['HTTP_REFERER'])

# 注销
def do_logout(request):
    try:
        logout(request)          #
    except Exception as e:
        logger.error(e)
    return redirect(request.META['HTTP_REFERER'])

# 注册
def do_reg(request):
    try:
        if request.method == 'POST':
            reg_form = RegForm(request.POST)
            if reg_form.is_valid():
                # 注册
                user = User.objects.create(username=reg_form.cleaned_data["username"],
                                    email=reg_form.cleaned_data["email"],
                                    url=reg_form.cleaned_data["url"],
                                    password=make_password(reg_form.cleaned_data["password"]),)
                user.save()

                # 登录
                user.backend = 'django.contrib.auth.backends.ModelBackend' # 指定默认的登录验证方式
                login(request, user)
                return redirect(request.POST.get('source_url'))
            else:
                return render(request, 'failure.html', {'reason': reg_form.errors})
        else:
            reg_form = RegForm()
    except Exception as e:
        logger.error(e)
    return render(request, 'reg.html', locals())

# 登录
def do_login(request):
    try:
        if request.method == 'POST':
            login_form = LoginForm(request.POST)
            if login_form.is_valid():
                # 登录
                username = login_form.cleaned_data["username"]
                password = login_form.cleaned_data["password"]
                user = authenticate(username=username, password=password)
                if user is not None:
                    user.backend = 'django.contrib.auth.backends.ModelBackend' # 指定默认的登录验证方式
                    login(request, user)
                else:
                    return render(request, 'failure.html', {'reason': '登录验证失败'})
                return redirect(request.POST.get('source_url'))
            else:
                return render(request, 'failure.html', {'reason': login_form.errors})
        else:
            login_form = LoginForm()
    except Exception as e:
        logger.error(e)
    return render(request, 'login.html', locals())

def category(request):
    try:
        # 先获取客户端提交的信息
        cid = request.GET.get('cid', None)
        try:
            category = Category.objects.get(pk=cid)
        except Category.DoesNotExist:
            return render(request, 'failure.html', {'reason': '分类不存在'})
        article_list = Article.objects.filter(category=category)
        article_list = paginator_list(request, article_list)
    except Exception as e:
        logger.error(e)
    return render(request, 'category.html', locals())

⑤.模板中的一个模块:
这个静态模板是我网上找的,然后经过熟悉,不断加入了动态效果,文章开头有完整的源码可以看看,还是那句话,我们刚开始不要急,可以先在网页显示一个静态文字,一个动态按钮,一个静态网页,一个登录界面,循序渐进,一定会豁然开朗有所收获:

{% extends 'base.html '%}
{% load static %}
{% block left_concent %}

    {% include 'ad.html' %}

    <div class="topnews">
      <h2>最新文章</h2>
        {% for article in article_list %}
      <div class="blogs">
        <ul>
          <h3><a href="/app1/article/?id={{article.id}}">{{article.title}}</a></h3>
          <p>{{article.desc}}</p>
          <p class="autor"><span class="lm f_l">{% for tag in article.tag.all %}<a href="/">{{tag.name}}</a></span>{% endfor %}<span class="dtime f_l">{{article.date_publish}}</span><span class="viewnum f_r">浏览(<a href="/">{{article.click_count}}</a></span><span class="pingl f_r">评论(<a href="/">{{article.comment_set.all.count}}</a></span></p>
        </ul>
      </div>
        {% endfor %}
    </div>

#分页代码
    {% include 'pagination.html' %}

  <!--<div id="pagination">-->
    <!--<ul id="pagination-flickr">-->
    <!--<li class="previous-off">&laquo;上一页</li>-->
      <!--<li class="active">1/10</li>-->
      <!--<li class="next"><a href="?page=8">下一页 &raquo;</a></li>-->
   <!--</ul>-->
   <!--</div>-->

{% endblock %}

⑥.数据库models.py及表单forms.py的建立:
models.py里面创建的数据表格想要可用,还需要执行数据迁移:在项目manage.py路劲下执行如下命令即可:
python manage.py makemigrations
python manage.py migrate
执行完成后如果没有报错,你会在数据库中看到生成了一堆数据表格,你对数据的增删改查都会在这些表格中进行:

# -*- coding:utf-8 -*-
from django.db import models
from django.contrib.auth.models import AbstractUser

from django.db.models.manager import Manager
# Create your models here.

# 用户模型.
class User(AbstractUser):
    avatar = models.ImageField(upload_to='avatar/%Y/%m', default='avatar/default.png', max_length=200, blank=True, null=True, verbose_name='用户头像')
    qq = models.CharField(max_length=20, blank=True, null=True, verbose_name='QQ号码')
    mobile = models.CharField(max_length=11, blank=True, null=True, unique=True, verbose_name='手机号码')#新增
    class Meta:
        verbose_name = '用户'
        verbose_name_plural = verbose_name
        ordering = ['-id']

    def __str__(self):
        return self.username

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

    class Meta:
        verbose_name = '标签'
        verbose_name_plural = verbose_name
        ordering = ['id']

    def __str__(self):
        return self.name

# 文章分类
class Category(models.Model):
    name = models.CharField(max_length=30, verbose_name='分类名称')
    index = models.IntegerField('显示顺序(从小到大)',default=999)

    class Meta:
        verbose_name = '分类'
        verbose_name_plural = verbose_name
        ordering = ['index', 'id']

    def __str__(self):
        return self.name


#自定义一个文章Model的管理器
#1.增加一个数据处理的方法
#2.改变原有的queryset
class ArticleManager(Manager):
    def distinct_date(self):
        distinct_date_list = []
        date_list = self.values('date_publish')

        for date in date_list:
            date = date['date_publish'].strftime('%Y-%m')
            if date not in distinct_date_list:
                distinct_date_list.append(date)
        return distinct_date_list

# 文章模型
class Article(models.Model):
    title = models.CharField(max_length=50, verbose_name='文章标题')
    desc = models.CharField(max_length=50, verbose_name='文章描述')
    content = models.TextField(verbose_name='文章内容')
    click_count = models.IntegerField(default=0, verbose_name='点击次数')
    is_recommend = models.BooleanField(default=False, verbose_name='是否推荐')
    date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间')
    user = models.ForeignKey(User, verbose_name='用户',on_delete=models.CASCADE)
    category = models.ForeignKey(Category, blank=True, null=True, verbose_name='分类', on_delete=models.CASCADE)
    tag = models.ManyToManyField(Tag, verbose_name='标签')

    # ... 其它已有的模型方法

    def click_count1(self):
        self.click_count += 1
        self.save(update_fields=['click_count'])

    objects = ArticleManager()

    class Meta:
        verbose_name = '文章'
        verbose_name_plural = verbose_name
        ordering = ['-date_publish']

    def __str__(self):
        return self.title

# 评论模型
class Comment(models.Model):
    content = models.TextField(verbose_name='评论内容')
    username = models.CharField(max_length=30, blank=True, null=True, verbose_name='用户名')   #新增
    email = models.EmailField(max_length=50, blank=True, null=True, verbose_name='邮箱地址')   #新增
    url = models.URLField(max_length=100, blank=True, null=True, verbose_name='个人网页地址')  #新增
    date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间')
    user = models.ForeignKey(User, blank=True, null=True, verbose_name='用户', on_delete=models.CASCADE)
    article = models.ForeignKey(Article, blank=True, null=True, verbose_name='文章', on_delete=models.CASCADE)
    pid = models.ForeignKey('self', blank=True, null=True, verbose_name='父级评论', on_delete=models.CASCADE)
    url = models.URLField(max_length=100, blank=True, null=True, verbose_name='个人网页地址')

    class Meta:
        verbose_name = '评论'
        verbose_name_plural = verbose_name
        ordering = ['-date_publish']

    def __str__(self):
        return str(self.id)

# 友情链接
class Links(models.Model):
    title = models.CharField(max_length=50, verbose_name='标题')
    description = models.CharField(max_length=200, verbose_name='友情链接描述')
    callback_url = models.URLField(verbose_name='url地址')
    date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间')
    index = models.IntegerField(default=999, verbose_name='排列顺序(从小到大)')

    class Meta:
        verbose_name = '友情链接'
        verbose_name_plural = verbose_name
        ordering = ['index', 'id']

    def __str__(self):
        return self.title

# 广告
class Ad(models.Model):
    title = models.CharField(max_length=50, verbose_name='广告标题')
    description = models.CharField(max_length=200,  verbose_name='广告描述')
    image_url = models.ImageField(upload_to='ad/%Y/%m', verbose_name='图片路径')
    callback_url = models.URLField(null=True, blank=True, verbose_name='回调url')
    date_publish = models.DateTimeField(auto_now_add=True, verbose_name='发布时间')
    index = models.IntegerField(default=999, verbose_name='排列顺序(从小到大)')

    class Meta:
        verbose_name = u'广告'
        verbose_name_plural = verbose_name
        ordering = ['index', 'id']

    def __str__(self):
        return self.title


# 几条常用的命令
# python manage.py makemigrations
# python manage.py syncdb
# python manage.py migrate


表单模块:就是不用html来做了输入框了,可以直接用表单模块做登录,评论,注册等模块:

# -*- coding:utf-8 -*-
from django import forms
from django.conf import settings
from django.db.models import Q
from app1.models import User
import re

class LoginForm(forms.Form):
    '''
    登录Form
    '''
    username = forms.CharField(widget=forms.TextInput(attrs={"placeholder": "Username", "required": "required",}),
                              max_length=50,error_messages={"required": "username不能为空",})
    password = forms.CharField(widget=forms.PasswordInput(attrs={"placeholder": "Password", "required": "required",}),
                              max_length=20,error_messages={"required": "password不能为空",})

class RegForm(forms.Form):
    '''
    注册表单
    '''
    username = forms.CharField(widget=forms.TextInput(attrs={"placeholder": "Username", "required": "required",}),
                              max_length=50,error_messages={"required": "username不能为空",})
    email = forms.EmailField(widget=forms.TextInput(attrs={"placeholder": "Email", "required": "required",}),
                              max_length=50,error_messages={"required": "email不能为空",})
    url = forms.URLField(widget=forms.TextInput(attrs={"placeholder": "Url", }),
                              max_length=100, required=False)
    password = forms.CharField(widget=forms.PasswordInput(attrs={"placeholder": "Password", "required": "required",}),
                              max_length=20,error_messages={"required": "password不能为空",})

class CommentForm(forms.Form):
    '''
    评论表单
    '''
    author = forms.CharField(widget=forms.TextInput(attrs={"id": "author", "class": "comment_input",
                                                           "required": "required","size": "25", "tabindex": "1"}),
                              max_length=50,error_messages={"required":"username不能为空",})
    email = forms.EmailField(widget=forms.TextInput(attrs={"id":"email","type":"email","class": "comment_input",
                                                           "required":"required","size":"25", "tabindex":"2"}),
                                 max_length=50, error_messages={"required":"email不能为空",})
    url = forms.URLField(widget=forms.TextInput(attrs={"id":"url","type":"url","class": "comment_input",
                                                       "size":"25", "tabindex":"3"}),
                              max_length=100, required=False)
    comment = forms.CharField(widget=forms.Textarea(attrs={"id":"comment","class": "message_input",
                                                           "required": "required", "cols": "25",
                                                           "rows": "5", "tabindex": "4"}),
                                                    error_messages={"required":"评论不能为空",})
    article = forms.CharField(widget=forms.HiddenInput())



之前也是抽出一部分时间来了解了一下网站开发,一个是锻炼一下逻辑思维,在一个是了解一下网络的结构,主要的是为了之后的数据挖掘及分析更加熟练;最终也是跟着视频完成了一个博客项目的制作,源码在上面已经分享了,供参考咯。

人生中在你努力追梦的时候总会有各种声音,有的告诉你前路平坦,有的告诉你前路崎岖,你的父母会劝你稳定就好,但是只有你自己知道,是否应该坚持;当然也许路上真的是没有光,看不见希望,有时候你会苦笑,是否应该放弃,也许坚持并没有什么意义,但是人生就是这样,放弃你也不一定会过的舒坦,坚持可能会更加痛苦,但这证明你还活着,相较于大部分人活的还挺好,因为还会纠结,说明有选择,有的人人生只有一条路;梦想也许很遥远,但是时间会给你答案。
我好累,但是真的还是幸福的。当一个能力不足的人站在舞台,我会感到尴尬,一个能力出众的人站在舞台,我会轻松面对,现在的坚持只是为了有一天当我站在舞台的时候,有人能从心底为我喝彩。

#持续更新,,,,,,,,,,,,

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值