#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">«上一页</li>-->
<!--<li class="active">1/10</li>-->
<!--<li class="next"><a href="?page=8">下一页 »</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())
之前也是抽出一部分时间来了解了一下网站开发,一个是锻炼一下逻辑思维,在一个是了解一下网络的结构,主要的是为了之后的数据挖掘及分析更加熟练;最终也是跟着视频完成了一个博客项目的制作,源码在上面已经分享了,供参考咯。
人生中在你努力追梦的时候总会有各种声音,有的告诉你前路平坦,有的告诉你前路崎岖,你的父母会劝你稳定就好,但是只有你自己知道,是否应该坚持;当然也许路上真的是没有光,看不见希望,有时候你会苦笑,是否应该放弃,也许坚持并没有什么意义,但是人生就是这样,放弃你也不一定会过的舒坦,坚持可能会更加痛苦,但这证明你还活着,相较于大部分人活的还挺好,因为还会纠结,说明有选择,有的人人生只有一条路;梦想也许很遥远,但是时间会给你答案。
我好累,但是真的还是幸福的。当一个能力不足的人站在舞台,我会感到尴尬,一个能力出众的人站在舞台,我会轻松面对,现在的坚持只是为了有一天当我站在舞台的时候,有人能从心底为我喝彩。
#持续更新,,,,,,,,,,,,