本教程分为三部分:思路、详细步骤、开发步骤,从上往下看,便于理解;
思路:
- 1.准备开发环境
- 2.学习基本的Django基础知识、搭建简单的polls系统
- 3.确定练手题材,比如我确定了做个家用的菜谱
- 4.寻找合适的html模板
- 5.根据网站需要添加学习添加新的数据类型,比如添加图片上传、添加富文本编辑
- 6.Windows下部署Django(Apache+mod_wsgi)
- 7.linux下部署Django(todo)
注意:没有接触过Django但是接触过python的情况下,完成前6步,大概需要2天的时间。
Django常用命令:
简单启动:python manage.py runserver
创建应用:python manage.py startapp xxx
检查app并创建相应的表:python manage.py migrate
激活model-生成sql:python manage.py makemigrations food
激活model-执行sql:python manage.py sqlmigrate food 0001
激活model-再次执行:python manage.py migrate
详细步骤
1.准备开发环境
主要涉及pythonCharm的安装、python3的安装,自己找教程搞定;
2.学习基本的Django基础知识、搭建简单的polls系统
参考官方文档:https://docs.djangoproject.com/zh-hans/2.1/
完成快速入门部分的学习,基本就能了解django的工作原理,各个文件的作用,并搭建一个简单的投票系统;
3.确定练手题材
根据第2步中学习的知识,自己做一个全新的网站。第一个网站不要太难,建议选择CMS(内容管理系统),我在选择的是家用菜谱。
功能需求:
- 管理后台可以新增、修改、删除菜单
- 编辑好的菜单,可以在页面显示
- 菜单参考饭店的二维码点餐目录:全部菜单、主食、素材、汤等
非功能性需求:
- 界面简洁美观,最好能自适应
二期拓展:
- 菜单可以评论
- 添加日历,记录当然的菜品或事件
- 优化后端界面操作等(xadmin)
4.寻找合适的html模板
我自己没有非常好的前端基础,如果从零写一套美观的界面,非常耗时且不能保证效果。所以我希望使用已有的前端模板,整合到Django中,略做调整就可以使用。
后来我从网上找了适合自己题材的模板:http://sc.chinaz.com/tag_moban/Html.html
下图是我选用的模板(链接:http://sc.chinaz.com/moban/180521171540.htm):
将模板整合到项目相应app的templates中去:
5.根据网站需要添加新的数据类型Ueditor、ImageField
菜单的内容肯定是图文的,所以我整合了Ueditor
content = UEditorField('内容', height=300, width=800, max_length=1024000000000,
default=u'', blank=True, imagePath="food/ueditor/images/",
toolbars='besttome', filePath='food/ueditor/files/')
菜单的索引页需要一张封面图片,所以我添加了图片上传功能;
show_pic = models.ImageField('照片', upload_to="food/ueditor/images/", blank=True, null=True)
6.Windows下部署Django(Apache+mod_wsgi)
在自己的电脑上部署一个局域网内的菜谱系统;
开发步骤
1.根据详细步骤-2走完之后,你的系统里面已经有一个叫polls的应用,可以添加问题、选项、可以投票;
2.创建我自己的应用food
2.1.创建food应用
python manage.py startapp food
2.2.确定文章内容的字段、确定model Article,只有一个model,刚开始所有的类型都用CharField
create_time、update_time、title、sub_title、article_type、author、key_word、show_pic、content
2.3.检查app并创建相应的表
python manage.py migrate
2.4.激活model
settings.py中添加:'food.apps.FoodConfig',
准备sql:python manage.py makemigrations food
执行sql:python manage.py sqlmigrate food 0001
再次执行:python manage.py migrate
2.5.管理后台中编译一条记录,然后再让它在页面中显示,可以显示title就可以了
2.6.修改model Article的字段-show_pic
首先将封面照片show_pic = models.CharField(max_length=50, null=True)
改为show_pic = models.ImageField('照片', upload_to="food/ueditor/images/", blank=True, null=True)
改完之后要做以下操作,才能生效(每次改完model都要这么执行):
激活model-生成sql:python manage.py makemigrations food
激活model-执行sql:python manage.py sqlmigrate food 0002
激活model-再次执行:python manage.py migrate
这里要注意settings中的static_url/static_root/media_url/media_root要先设置好
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
文件上传后,会根据media_url和models.ImageField中的upload_to,确定图片的保存路径,如图:
2.7.上传的文件需要正常显示,必须设置好url:
# 媒体文件想要通过ip地址访问到静态文件要做如下配置
url(r'^media/(?P.*)$', serve, {"document_root": settings.MEDIA_ROOT}, name='media')
2.8.修改model Article的字段-content
2.8.1)下载DjangoUeditor:
python3: https://github.com/twz915/DjangoUeditor3/ (直接下载zip)
2.8.2)在项目的根目录新建extra_apps文件夹并将我们下载好的zip文件解压,
打开后找到 DjangoUeditor将DjangoUeditor直接拷贝到我们项目的extra_apps中,如图:
2.8.3)在settings.py文件中添加两行代码:如下
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
sys.path.insert(0, os.path.join(BASE_DIR, 'extra_apps'))
2.8.4)通过pycharm 选中extra_apps文件夹点击鼠标右键选中菜单mark directory as 选择 sources root就可以变成上面的蓝色文件夹目录就可以了。
2.8.5)变成蓝色文件夹后就可以在settings.py 的INSTALLED_APPS中引入DjangoUeditor,如下:
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'food.apps.FoodConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'DjangoUeditor',
]
2.8.6)在的settings同级的urls.py中添加ueditor:
path('ueditor/', include('DjangoUeditor.urls')),
2.8.7) 将content改成Ueditor
content = UEditorField('内容', height=300, width=800, max_length=1024000000000,
default=u'', blank=True, imagePath="food/ueditor/images/",
toolbars='besttome', filePath='food/ueditor/files/')
改完之后要做以下操作,才能生效(每次改完model都要这么执行):
激活model-生成sql:python manage.py makemigrations food
激活model-执行sql:python manage.py sqlmigrate food 0002
激活model-再次执行:python manage.py migrate
2.8.8)问题:Ueditor的图片不展示
因为img的src 没有域名,确保DjangoUeditor中的views.py244行,数据返回的格式正确,如图:
2.9.Html迁移相关问题
注意1目录分布
注意2css的相对路径
注意3左侧li选中active效果
全部菜单
2.10.相关代码参考
2.10.1food应用下的models
import datetime
from django.db import models
# Create your models here.
from django.utils import timezone
from DjangoUeditor.models import UEditorField
class Article(models.Model):
create_time = models.DateTimeField('创建时间')
update_time = models.DateTimeField('更新时间')
title = models.CharField(max_length=100, null=True)
sub_title = models.CharField(max_length=100, null=True)
article_type = models.CharField(max_length=50, null=True)
author = models.CharField(max_length=50, null=True)
key_word = models.CharField(max_length=50, null=True)
# show_pic = models.CharField(max_length=50, null=True)
# show_pic = models.ImageField(upload_to="icons", height_field='url_height', width_field='url_width')
show_pic = models.ImageField('照片', upload_to="food/ueditor/images/", blank=True, null=True)
content = UEditorField('内容', height=300, width=800, max_length=1024000000000,
default=u'', blank=True, imagePath="food/ueditor/images/",
toolbars='besttome', filePath='food/ueditor/files/')
def show_pic_url(self):
if self.show_pic and hasattr(self.show_pic, 'url'):
return self.show_pic.url
else:
return '/media/default/user.jpg'
def __str__(self):
return self.title
def was_published_recently(self):
now = timezone.now()
return now - datetime.timedelta(days=1) <= self.update_time <= now
was_published_recently.admin_order_field = 'update_time'
was_published_recently.boolean = True
was_published_recently.short_description = 'Published recently?'
2.10.2food应用下的urls.py
from food import views
from food.views import page_not_found
app_name = 'food'
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('staple_food', views.StapleFoodView.as_view(), name='staple_food'),
path('half', views.HalfOfMeat.as_view(), name='half'),
path('big', views.BigMeat.as_view(), name='big'),
path('vegetable', views.Vegetable.as_view(), name='vegetable'),
path('soup', views.Soup.as_view(), name='soup'),
path('cold', views.Cold.as_view(), name='cold'),
path('/', views.DetailView.as_view(), name='detail'),
]
# 定义错误跳转页面
# handler403 = permission_denied
handler404 = page_not_found
# handler500 = page_error
2.10.3food应用下的views.py
# Create your views here.
from django.shortcuts import render
from django.views import generic
from food.models import Article
class IndexView(generic.ListView):
template_name = 'food/index.html'
context_object_name = 'latest_article_list'
def get_queryset(self):
"""Return the last five published questions."""
print(Article.objects.all())
return Article.objects.all()
# return Article.objects.filter(update_time__lte=timezone.now()).order_by('-update_time')[:5]
class DetailView(generic.DetailView):
model = Article
template_name = 'food/detail.html'
class StapleFoodView(generic.ListView):
template_name = 'food/index.html'
context_object_name = 'latest_article_list'
def get_queryset(self):
"""Return the last five published questions."""
print(Article.objects.all())
return Article.objects.filter(article_type__contains="staple")
class HalfOfMeat(generic.ListView):
template_name = 'food/index.html'
context_object_name = 'latest_article_list'
def get_queryset(self):
"""Return the last five published questions."""
print(Article.objects.all())
return Article.objects.filter(article_type__contains="half")
class BigMeat(generic.ListView):
template_name = 'food/index.html'
context_object_name = 'latest_article_list'
def get_queryset(self):
"""Return the last five published questions."""
print("大荤:")
print(Article.objects.filter(article_type__contains="big"))
return Article.objects.filter(article_type__contains="big")
# 素菜
class Vegetable(generic.ListView):
template_name = 'food/index.html'
context_object_name = 'latest_article_list'
def get_queryset(self):
"""Return the last five published questions."""
print(Article.objects.all())
return Article.objects.filter(article_type__contains="vegetable")
# 凉菜
class Cold(generic.ListView):
template_name = 'food/index.html'
context_object_name = 'latest_article_list'
def get_queryset(self):
"""Return the last five published questions."""
print(Article.objects.all())
return Article.objects.filter(article_type__contains="cold")
# 汤
class Soup(generic.ListView):
template_name = 'food/index.html'
context_object_name = 'latest_article_list'
def get_queryset(self):
"""Return the last five published questions."""
print(Article.objects.all())
return Article.objects.filter(article_type__contains="soup")
# 全局403、404、500错误自定义页面显示
def page_not_found(request):
return render(request, 'food/404.html')
def page_error(request):
return render(request, '500.html')
def permission_denied(request):
return render(request, '403.html')
2.10.4food应用下的admin.py
from django.contrib import admin
# Register your models here.
from food.models import Article
class ArticleAdmin(admin.ModelAdmin):
fields = ['create_time', 'update_time', 'title', 'sub_title', 'article_type', 'author', 'key_word', 'show_pic',
'content']
list_display = ('create_time', 'update_time', 'title', 'sub_title', 'article_type', 'author', 'key_word', 'show_pic')
admin.site.register(Article, ArticleAdmin)
3.Windows下部署Django(Apache+mod_wsgi)
详细步骤参考:https://www.jianshu.com/p/598d8b5fbee6
注意的问题:
1.Apache24安装后启动不起来
1)、在cmd命令行进入Apache24/bin目录下
2)、执行httpd -t命令
3)、会看到错误提示:(仅仅是我的情况)AH00526:
Syntax error on line 34 of F:/Apache/Apache/conf/extra/httpd-ahssl.conf:SSLProtocol: Illegal protocol 'TLSv1.3'
4)、先进入到这个文件改34行,SSLProtocol -all +TLSv1.2 +TLSv1.3发现怎么改都没有用,看了下他的上一行
把改成问题解决了
2.mod_wsgi的安装、检查最好在cmd中,否则mod_wsgi-express module-config出现不了3条准确的记录;再pythonCharm的terminal执行只有2条记录;
3.Django已经安装,而且pythonCharm运行的时候正常,但是windows下部署,apache的错误日志中提示Django未安装:
windows下部署,注意pythoncharm中安装的django路径可能和python不一样;需要在命令行重新安装;注意安装的时候指定版本;
效果图
4.部署到linux
TODO