Django项目于之在线教育平台网站的实战开发(完结)

news/2024/5/10 17:43:30/文章来源:https://cdtaogang.blog.csdn.net/article/details/90243762

说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

接着上一篇博客继续往下写 :https://blog.csdn.net/qq_41782425/article/details/90141577

项目源码下载 

目录

一丶常见web攻击及防范

二丶Xadmin多种配置

三丶Xadmin插件开发(富文本编辑器)

四丶Xadmin插件开发(导出excel)

五丶项目部署上线

六丶项目总结


一丶常见web攻击及防范

1.sql注入攻击与防范

① sql注入的危害

  • 非法读取丶篡改丶删除数据库中的数据
  • 盗取用户的各类敏感信息,获取利益
  • 通过修改数据库来修改网页上的内容
  • 注入木马等

② sql注入登录演示

  • 定义原始方法登录视图
# sql注入登录演示
class UnsafeLoginView(View):"""不安全登录,使用最原始的方法进行登录"""def get(self, request):return render(request, "login.html")def post(self, request):user_name = request.POST.get("username", "")pass_word = request.POST.get("password", "")import MySQLdbconn = MySQLdb.connect(host="127.0.0.1", user="root", passwd="mysql", db="mxonline", charset="utf8")cursor = conn.cursor()sql = "select * from  users_userprofile where username = '{0}' and password = '{1}' ".format(user_name, pass_word)res = cursor.execute(sql)# 获取用户所有数据all_users = cursor.fetchall()
  • 在根级urls中修改登录视图为上一步定义的视图
url(r'^login/$', UnsafeLoginView.as_view(), name="login"),  # 登录页
  •  Debug测试输入不存在的用户名和密码,res变量的值为0,表示未查询到结果

  • 在登录页面,输入特殊的用户名,密码随便输入,如下图所示

  •  Debug测试的结果是,居然查询到了数据,原因是1=1此条件为真所以肯定能查询到数据

  • 使用以上的sql语句在数据库进行查询,同样也能查询到数据

2.xss攻击原理及防范

xss跨站脚本攻击(Cross Site Scripting)的危害

  • 盗取各类用户账号,如用户网银账号丶各类管理员账号
  • 盗窃企业重要的具有商业价值的资料
  • 非法转账
  • 控制受害者机器向其他网站发起攻击丶注入木马等

xss攻击原理

  • 服务器对用户发送的请求地址中的name属性的值,直接做回显,并没有做任何加密处理,当黑客将请求地址中的name属性的值修改成一段js脚本,比如下图所示的获取cookie并进行alert打印,那么就会获取到用户的保存在本地的cookie

xss攻击流程图 

  • 以下的js脚本只是其中的一种而已,而黑客是怎么将url发送给受害者的比如邮件,QQ等等

xss攻击防范

  • 首先代码里对用户输入的地方和变量都需要仔细检查长度和对(" <" >" ; ')等字符做过滤
  • 避免直接在cookie中泄露用户隐私,例如email丶密码等等
  • 通过使cookie和系统ip进行绑定来降低cookie泄露后的危险
  • 尽量采用POST进行表单提交而不使用GET(也就是请求地址中不出现参数)

3.csrf攻击与防范

csrf跨站请求伪造(Cross-site request forgery)的危害

  • 以你的名义进行邮件发送
  • 盗取你的账号
  • 购买商品
  • 虚拟货币转账

csrf攻击原理

csrf防范

  • 表单提交时加上打印出csrf_token的值即可对跨站攻击进行有效的防范{% csrf_token %}

二丶Xadmin多种配置

1.导航栏icon的修改

  • 首先登陆Font Awesome官网,下载最新版本图标字体库以及CSS框架

  • 在xadmin源码中查看当前使用的font-awesome的版本为4.0.3

  • 将下载好的font-awesome-4.7.0进行解压后,替换编辑器源码中的font-awesome目录文件

  • 在xadmin后端页面中左侧导航栏,修改用户心下的邮箱验证码图标

  • 在xadmin源码中auth.py模块中找到UserAdmin模型类中的图标属性变量为model_icon

  • 即在users/adminx中找到邮箱验证码的EmailVerifyRecordAdmin类,在类中添加model_icon属性,具体需要改成什么样的图标,需要在官网上找到要修改图片样式,如下图所示

  • 然后紧接着在EmailVerifyRecordAdmin邮箱验证码注册类中执行model_icon属性为上图的样式

  • Ctrl+F5强制刷新xadmin后台,用户信息邮箱验证码的图标就修改成功了

2.xadmin后台表数据设定默认字段排序

  • 比如当用户点击查看课程列表时,整个列表数据是乱序的,比如点击数

  • 想让课程列表中的数据按照点击数的倒序进行排序,就需要在对应的注册类中添加如下ordering属性即可
class CourseAdmin(object):list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'click_nums']search_fields = ['name', 'desc', 'detail', 'degree', 'students']list_filter = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students']ordering = ['-click_nums']
  • 刷新页面,成功按照课程点击数倒序排列显示数据

3.xadmin后台管理中字段设置为只读

  • 在课程数据中如点击数丶收藏认识丶学习人数应该是只读而不能进行修改编辑的

  • 在注册类中添加readonly_fields属性指向要只读的字段
readonly_fields = ['students', 'click_nums', 'fav_nums']
  • 刷新页面则,指定只读的字段则显示在页面底部

4.在xadmin后台中不显示某些字段

  • 在注册类中添加exclude属性的值即可,需要注意的是exclude属性与readonly_fields属性时冲突的,所以需要去除readonly_fields属性中的click_nums字段
readonly_fields = ['students', 'fav_nums']
exclude = ['click_nums']
  • 刷新页面则,不显示点击数字段

5.增加课程时修改外键选择的样式

  • 增加一门课程,需要通过下拉框来选择对应课程的机构,当数据庞大时,使用下拉框就没有搜索框来的方便

  • 在organization/adminx中找到外键所指向的注册类,在该类中设置样式
relfield_style = 'fk-ajax'
  • 刷新页面,在选择课程机构时则成功显示出搜索框

6.inline的使用

  • 在xadmin后台管理中为课程添加章节信息时,不能在增加课程页面直接添加,而是需要退出课程到章节字段中去选择课程后才能添加课程的章节信息,在xadmin中也能像django admin那样去做到在一个页面直接添加外键的信息,在课程管理的adminx中需要定义一个类LessonInline,通过课程注册类中添加inlines的属性指向LessonInline对象即可达到效果
class LessonInline(object):model = Lessonextra = 0class CourseAdmin(object):list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'click_nums']search_fields = ['name', 'desc', 'detail', 'degree', 'students']list_filter = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students']ordering = ['-click_nums']readonly_fields = ['students', 'fav_nums']exclude = ['click_nums']inlines = [LessonInline]
  • 刷洗页面,增加课程页面底部就会出现章节,点击+则可以添加该课程对应的章节信息,很是方便

  • 需要注意的是,inline只能完成一成嵌套,不能完成多层,比如课程---章节---视频这就没法,但一个课程对应多个外键,就可以在inlines 属性中添加多个类,因为是列表类型的变量,在课程增加页面,除了添加章节还可以添加课程资源
class LessonInline(object):model = Lessonextra = 0class CourseResourceInline(object):model = CourseResourceextra = 0class CourseAdmin(object):list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'click_nums']search_fields = ['name', 'desc', 'detail', 'degree', 'students']list_filter = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students']ordering = ['-click_nums']readonly_fields = ['students', 'fav_nums']exclude = ['click_nums']inlines = [LessonInline, CourseResourceInline]
  • 刷新页面,在增加课程页面就可以同时添加章节信息以及课程资源数据了

7.自定义列表返回数据,同一个model注册两个管理器

  • 在之前主页动态数据展示时,因公开课程栏中嵌套了轮播图,就需要在课程所在的模型类Course添加is_banner是否轮播字段

  • 如果想在课程管理中产生另一个表数据,这个表数据只显示轮播的课程数据那么就需要在courses/models中创建一个轮播课程模型类,这个类必须继承Course,只需要在类中编写Meta类并定义名称即可
class BannerCourse(Course):class Meta:verbose_name = "轮播课程"verbose_name_plural = verbose_nameproxy = True
  • 将上面定义的模型类,在courses/adminx中进行导入注册
class BannerCourseAdmin(object):list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'click_nums']search_fields = ['name', 'desc', 'detail', 'degree', 'students']list_filter = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students']ordering = ['-click_nums']readonly_fields = ['students', 'fav_nums']exclude = ['click_nums']inlines = [LessonInline, CourseResourceInline]xadmin.site.register(BannerCourse, BannerCourseAdmin)
  • 强制刷新页面后,在课程管理导航栏下成功创建一个轮播课程表数据,这个数据说白了跟课程的数据一模一样只是名称变了

  • 如何让轮播课程表中数据只显示轮播的课程,在轮播课程对应的注册类中定义一个方法,该方法用于对父类Course模型类中的is_banner字段进行过滤,将过滤后的数据进行返回即可,为什么可以对is_banner字段进行过滤,因为BannerCourseAdmin与BannerCourse进行注册关联,并且BannerCourse这个模型类又继承Course模型类,即可以对is_banner字段进行过滤处理了
class BannerCourseAdmin(object):list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'click_nums']search_fields = ['name', 'desc', 'detail', 'degree', 'students']list_filter = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students']ordering = ['-click_nums']readonly_fields = ['students', 'fav_nums']exclude = ['click_nums']inlines = [LessonInline, CourseResourceInline]def queryset(self):qs = super(BannerCourseAdmin, self).queryset()qs = qs.filter(is_banner=True)return qs
  • 刷新页面查看轮播课程数据,则成功只显示轮播的课程数据

  • 既然在轮播课程中只显示轮播课程数据,那么在课程中也应当只显示出不轮播的课程数据,跟上面同理在CourseAdmin注册类中定义queryset方法,只需要修改父类名以及将filter方法中的条件改成False即可
class CourseAdmin(object):list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'click_nums']search_fields = ['name', 'desc', 'detail', 'degree', 'students']list_filter = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students']ordering = ['-click_nums']readonly_fields = ['students', 'fav_nums']exclude = ['click_nums']inlines = [LessonInline, CourseResourceInline]def queryset(self):qs = super(CourseAdmin, self).queryset()qs = qs.filter(is_banner=False)return qs
  • 查看课程下的数据,只有13条,总共课程16条数据,轮播课程3条,所以数据筛选正确

8.list_editable属性

  • 在课程注册类CourseAdmin中添加list_editable属性,这个属性可以在列表中对设定的字段直接进行编辑,而不需要点击进入课程详情中进行编辑
list_editable = ['name', 'degree']
  • 刷新课程列表页面,则指定可编辑的name字段以及degree字段则出现编辑按钮,点击按钮可直接进行编辑保存了

9.在课程列表中显示对应课程的章节数

  • 之前在页面模板中为了显示课程的章节数,在Course模型类中定义了get_zj_nums方法,用于获取课程的章节数,short_description方法是用于在xadmin后台显示的字段名称
def get_zj_nums(self):#获取课程章节数return self.lesson_set.all().count()
get_zj_nums.short_description = "章节数"
  • 在课程注册类CourseAdmin中list_display属性中添加该方法名,对应django来说判断该字段为方法名时,则会去调用此方法
list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'click_nums', "get_zj_nums"]
  • 刷新课程列表页,则成功显示出课程对应的章节数

10.在课程列表字段添加跳转按钮,指定跳转的链接地址

  • 在Course模型类中定义go_to方法,具体如下,说明一下make_safe方法是让链接地址安全不进行转义操作
def go_to(self):from django.utils.safestring import mark_safereturn mark_safe("<a href='http://www.baidu.com'>跳转</a>")
go_to.short_description = "跳转"
  • 在注册类CourseAdmin中将以上方法名添加到list_display属性中
list_display = ['name', 'desc', 'detail', 'degree', 'learn_times', 'students', 'click_nums', "get_zj_nums", "go_to"]
  • 测试显示跳转字段并进行目标地址的跳转

11.页面定时刷新插件

  • xadmin提供了此功能,在RefreshPlugin类中refresh_times为空列表,表示未进行设置刷新时间

  • 在CourseAdmin中添加refresh_times属性,并设定其值为3秒或5秒刷新条件
refresh_times = [3, 5]
  • 测试自动刷新,选择3秒进行刷新测试,请注意链接地址的自动刷新

12.在保存课程的时候统计课程机构的课程数

  • 在CourseAdmin注册类中重写父类的save_models方法,当对课程进行修改或者增加时都会对数据进行保存,那么就会去调用重写的save_models方法,就可以在这个方法中查询获取对应的课程机构的课程数
def save_models(self):# 在保存课程的时候统计课程机构的课程数obj = self.new_objobj.save()if obj.course_org is not None:course_org = obj.course_orgcourse_org.course_nums = Course.objects.filter(course_org=course_org).count()course_org.save()
  • 在课程机构中查看第一条数据同济大学的课程数,这里显示为0

  • Debug 断点测试,在课程中对Mysql主从复制课程所属的课程机构修改成同济大学,后点击保存

  • Debug断点测试完成后,查看课程机构中同济大学的课程数

三丶Xadmin插件开发(富文本编辑器)

说明: django ueditor富文本编辑器的集成

1.Xadmin插件制作官方中文文档 Xadmin 插件制作 — Django Xadmin 2.1.5 beta documentation

2.DjangoUeditor源码文档 GitHub - zhangfisher/DjangoUeditor: DjangoUeditor

3.DjangoUeditor使用

  • 安装DjangoUeditor

  • 在INSTALL_APPS里面增加DjangoUeditor
INSTALLED_APPS = ['django.contrib.admin',.......,.......,"pure_pagination","DjangoUeditor"
]
  • 配置urls
url(r'^ueditor/',include('DjangoUeditor.urls' )),
  • 在需要使用富文本编辑器的模型类中导入UEditorField类,项目中Course模型类中的课程详情字段是需要使用富文本的,所以对detail字段进行如下修改
  • 说明:UEditorField继承自models.TextField,因此你可以直接将model里面定义的models.TextField直接改成UEditorField即可
detail = UEditorField(verbose_name=u"课程详情",width=600, height=300, imagePath="courses/ueditor/",filePath="courses/ueditor/", default='')
  • 在xadmin/plugins目录下创建ueditor.py文件,在文件中进行如下编写
import xadmin
from xadmin.views import BaseAdminPlugin, CreateAdminView, ModelFormAdminView, UpdateAdminView
from DjangoUeditor.models import UEditorField
from DjangoUeditor.widgets import UEditorWidget
from django.conf import settingsclass XadminUEditorWidget(UEditorWidget):def __init__(self,**kwargs):self.ueditor_options=kwargsself.Media.js = Nonesuper(XadminUEditorWidget,self).__init__(kwargs)class UeditorPlugin(BaseAdminPlugin):def get_field_style(self, attrs, db_field, style, **kwargs):if style == 'ueditor':if isinstance(db_field, UEditorField):widget = db_field.formfield().widgetparam = {}param.update(widget.ueditor_settings)param.update(widget.attrs)return {'widget': XadminUEditorWidget(**param)}return attrsdef block_extrahead(self, context, nodes):js = '<script type="text/javascript" src="%s"></script>' % (settings.STATIC_URL + "ueditor/ueditor.config.js")         #自己的静态目录js += '<script type="text/javascript" src="%s"></script>' % (settings.STATIC_URL + "ueditor/ueditor.all.min.js")   #自己的静态目录nodes.append(js)xadmin.site.register_plugin(UeditorPlugin, UpdateAdminView)
xadmin.site.register_plugin(UeditorPlugin, CreateAdminView)
  • 在xadmin/plugins目录下的__init__.py文件中,将ueditor插件注册进去
PLUGINS = ('actions', '.......','ueditor',
)

4.错误修正 

说明:DjangoUeditor是基于Python 2.7的进行开发的,博主这里的开发环境为python3,所以需要对DjangoUeditor安装包下的models.py丶settings.py丶widgets.py丶commands.py丶urls.py丶views.py进行修改

  • models.py 
# from widgets import UEditorWidget,AdminUEditorWidget
from .widgets import UEditorWidget, AdminUEditorWidget
  • settings.py
更新配置:从用户配置文件settings.py重新读入配置UEDITOR_SETTINGS,覆盖默认
def UpdateUserSettings():UserSettings=getattr(gSettings,"UEDITOR_SETTINGS",{}).copy()# if UserSettings.has_key("config"):UEditorSettings.update(UserSettings["config"])# if UserSettings.has_key("upload"):UEditorUploadSettings.update(UserSettings["upload"])if UserSettings.get("config"):UEditorSettings.update(UserSettings["config"])if UserSettings.get("upload"):UEditorUploadSettings.update(UserSettings["upload"])
  • widgets.py
# import settings as USettings
# from  commands import *
from . import settings as USettings
from .commands import *
  • commands.py
# import settings as USettings
from . import settings as USettings
  • urls.py
#coding:utf-8
# from django import VERSION
# if VERSION[0:2]>(1,3):
#     from django.conf.urls import patterns, url
# else:
#     from django.conf.urls.defaults import patterns, url
#
# from views import get_ueditor_controller
#
# urlpatterns = patterns('',
#     url(r'^controller/$',get_ueditor_controller)
# )
from .widgets import UEditorWidget, AdminUEditorWidget
from .views import get_ueditor_controller
from django.conf.urls import urlurlpatterns = [url(r'^controller/$', get_ueditor_controller),
]
  • views.py
# import settings as USettings
from . import settings as USettings#保存上传的文件
def save_upload_file(PostFile,FilePath):try:f = open(FilePath, 'wb')for chunk in PostFile.chunks():f.write(chunk)# except Exception,E:#     f.close()#     return u"写入文件错误:"+ E.message# f.close()# return u"SUCCESS"except Exception as E:f.close()return u"写入文件错误:"+ E.messagef.close()return u"SUCCESS"
  • 重启项目进入xadmin后台进行增加课程操作时,结果报错了

  • 回到编辑器,查看错误位置

  • 查看安装包DjangoUeditor中发现并没有ueditor.html,甚至连templates目录都没有

解决方法有三种:第一种就是在github上将别人修正好的适合python3的DjangoUeditor源码拷贝进行源码安装;第二种就是自己下载DjangoUeditor免安装源码放在项目extra_apps目录下;第三种就是下载DjangoUeditor源码安装,在对其下的模块进行修正

  • 博主选择第三种,将下载好的DjangoUeditor-master.zip进行解压,将解压后的文件放在项目根目录下,具体操作如下

  • 完成上一步后,刷新页面则成功在课程详情字段加载出富文本编辑器

  • 添加新的课程使用富文本编辑器

  • 查看课程列表,在刚新增的课程详情页中显示全是HTML代码

  • 在进入课程详情后,详情页面显示出转义的内容

  • 需要在course-detail模板中找到课程详情数据块,对数据块内容进行转义关闭
<div class="tab_cont tab_cont1">{% autoescape off %}<p>{{ course.detail }}</p>{% endautoescape %}
</div>
  •  刷新页面,成功显示出在富文本编写的内容

5.总结步骤:

安装
1.pip install DjangoUeditor
2.settings.py 中加入DjangoUeditor
3.url(r'ueditor/', include('DjangoUeditor.urls'))
4.detail = UeditorField()xadmin
1.plugins中添加ueditor.py文件,在__init__中加入ueditor
2.adminx中添加style_fields = {'detail':'ueditor'}

四丶Xadmin插件开发(导出excel)

说明:excel的导入插件开发

1.在xadmin/plugins中创建excel.py文件,拷贝如下内容

import xadmin
from xadmin.views import BaseAdminPlugin, ListAdminView
from django.template import loader
from xadmin.plugins.utils import get_context_dict#excel 导入
class ListImportExcelPlugin(BaseAdminPlugin):import_excel = Falsedef init_request(self, *args, **kwargs):return bool(self.import_excel)def block_top_toolbar(self, context, nodes):nodes.append(loader.render_to_string('xadmin/excel/model_list.top_toolbar.import.html', context=get_context_dict(context)))xadmin.site.register_plugin(ListImportExcelPlugin, ListAdminView)

2.在xadmin/templates/xadmin目录下创建excel目录,在目录下创建model_list.top_toolbar.import.html文件,文件内容如下

{% load i18n %}
<div class="btn-group export"><a class="dropdown-toggle btn btn-default btn-sm" data-toggle="dropdown" href="#"><i class="icon-share"></i> 导入 <span class="caret"></span></a><ul class="dropdown-menu" role="menu" aria-labelledby="dLabel"><li><a data-toggle="modal" data-target="#export-modal-import-excel"><i class="icon-circle-arrow-down"></i> 导入 Excel</a></li></ul><script>function fileChange(target){
//检测上传文件的类型var imgName = document.all.submit_upload.value;var ext,idx;if (imgName == ''){document.all.submit_upload_b.disabled=true;alert("请选择需要上传的 xls 文件!");return;} else {idx = imgName.lastIndexOf(".");if (idx != -1){ext = imgName.substr(idx+1).toUpperCase();ext = ext.toLowerCase( );
{#                    alert("ext="+ext);#}if (ext != 'xls' && ext != 'xlsx'){document.all.submit_upload_b.disabled=true;alert("只能上传 .xls 类型的文件!");return;}} else {document.all.submit_upload_b.disabled=true;alert("只能上传 .xls 类型的文件!");return;}}}</script><div id="export-modal-import-excel" class="modal fade"><div class="modal-dialog"><div class="modal-content"><form method="post" action="" enctype="multipart/form-data">{% csrf_token %}<div class="modal-header"><button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button><h4 class="modal-title">导入 Excel</h4></div><div class="modal-body"><input type="file" onchange="fileChange(this)" name="excel" id="submit_upload"></div><div class="modal-footer"><button type="button" class="btn btn-default" data-dismiss="modal">{% trans "Close" %}</button><button class="btn btn-success" type="submit" id="submit_upload_b"><i class="icon-share"></i> 导入</button></div></form></div><!-- /.modal-content --></div><!-- /.modal-dalog --></div><!-- /.modal --></div>

3.在courses/adminx下的CourseAdmin类中添加import_excel = True属性,并定义一个post方法,在这个方法中可以任意添加任何逻辑代码,这里就不进行逻辑代码的演示了,直接pass,但必须返回如下调用,不然会出错

def post(self, request, *args, **kwargs):if 'excel' in request.FILES:passreturn super(CourseAdmin, self).post(request, args, kwargs)

4.在plugins/__init__.py中注册此插件

PLUGINS = ('actions', 'filters', 'bookmark', 'export', 'ueditor','excel',
)
  • 测试刷新课程列表页,在右上角菜单栏中显示出导入按钮,因为没有写对上传excel文件操作,所以这里只能显示出此功能

 五丶项目部署上线

1.指定python3版本创建django_py3虚拟环境,并进入此环境

2.安装项目所需的包

3.查看当前虚拟环境下的包

4.运行项目

  • 在终端执行python3 manage.py runserver

  • 结果报错了,这个错无非就是安装的DjangoUeditor包中源码为python2编写的 

  • 将windows虚拟环境D:\django_py3\Lib\site-packages下的DjangoUeditor包替换掉ubuntu虚拟环境django_py3/lib/python3.5/site-packages下的DjangoUeditor

  • 再次使用命令启动项目,结果又报错了,原因是没有mxonline的数据库

5.将windows上的mxonline数据库数据传输到ubuntu中

  • 在ubuntu中创建mxonline数据库 

  • 查看ubuntu上的IP地址

  • 博主这里在使用Navicat软件时,不小心将mxonline数据库数据表数据清空了,所以导致博主需要花大量时间在xadmin后台进行数据的添加,所以博主先将数据库mxonline进行备份,免得再出现该情况

  • 使用Navicat软件测试在windows上测试连接ubuntu中的mysql 

  • 在Windows上打开Navicat软件,通过该软件数据传输功能将mxonline数据库数据传输到ubuntu中的mxonline数据中

  • 点击开始后,出现success表示成功

  • 回到ubuntu中,重新启动项目,则启动成功

  • 打开浏览器访问成功访问主页并显示动态数据

6.安装nginx

说明:安装过程不用演示,很简单

  • 因博主在之前Django电商项目中已经安装过了所以这里不用安装,并且ngin.conf配置文件中的配置为Django电商项目的配置;在Django电商项目部署配置nginx时,将默认的配置文件进行了备份(nginx.conf.fefault),所以只需要指定该配置文件来启动nginx即可

  • 在浏览器中直接输入ubuntu IP地址即默认访问80端口,则显示nginx服务启动成功页面

7.安装uwsgi

  • 进入虚拟环境中安装uwsgi

  • 使用uwsgi启动项目

  • 在浏览器中输入http://192.168.4.63:8000/ 则成功加载出页面动态数据;但静态资源无法加载出来

8.nginx配置

  • 拷贝nginx默认的配置文件到当前目录下并命名为mx_nginx.conf

  • 编写mx_nginx.conf文件内容,具体如下
server {listen       80;server_name  192.168.4.63 www.mxonline.com;#charset koi8-r;#access_log  logs/host.access.log  main;location /static {alias /home/taogang/Desktop/MxOnline/static;}location /media {alias /home/taogang/Desktop/MxOnline/media;}location / {include   uwsgi_params;uwsgi_pass  127.0.0.1:8000;}
}
  • 指定以上配置文件启动nginx服务器

9.将项目所用到的所有静态资源文件收集到static目录下

  • 需要在settings配置文件中配置收集静态文件路径,之前Django电商项目也是这样的

  • 进入项目虚拟环境,执行命令进行收集

10.创建并配置uwsgi.ini文件

  • 在项目根目录下创建一个uwsgi.ini配置文件,编写以下内容

  • 在配置文件settings中,设置为线上环境
DEBUG = FalseALLOWED_HOSTS = ['*']

11.测试使用uwsgi启动项目

  • 启动uwsgi

  • 在浏览器直接访问http://192.168.4.63/ 成功加载动态数据以及静态资源文件

12.在windows中使用域名访问网站

  • 切换到windows中,在浏览器输入http://192.168.4.63/  成功访问ubuntu中uwsgi启动的网站,之所以能够访问是因为通过vmware虚拟机搭建的ubuntu桥接模式为同一网段ip,即可以互相ping通

  • 接下来想要在浏览器地址栏中输入www.mxonline.com域名来访问网站主页,则需要在windows电脑hosts文件中添加如下内容,则表示输入此域名相当于访问192.168.4.63IP地址,因为没有购买域名,所以只能这样做,仅限于本地可以使用该域名访问

  • 测试在浏览器中输入mxonline.com -  是否成功访问主页

六丶项目总结

1.数据库设计

  • users app model用户信息相关数据表设计
  • organization app model课程机构数据表设计
  • courses app model课程相关数据表设计
  • operation app model用户操作相关数据表设计

2.后台管理系统开发

  • xadmin安装以及model注册
  • xadmin全局配置

3.登录和注册以及找回密码

  • 登录(session和cookie机制)
  • 注册(form表单提交和图片验证码以及发送邮件)
  • 找回密码(邮件发送)

4.课程机构

  • 机构列表(分页和筛选以及排序)
  • 机构详情(收藏和富文本编辑)
  • 咨询提交(modelform验证和保存)

5.课程功能

  • 课程列表(分页和排序)
  • 课程详情(收藏丶章节展示丶资源展示丶评论)

6.讲师功能

  • 讲师列表(分页和排序)
  • 讲师详情(收藏)

7.个人中心

  • 用户信息修改(修改密码丶头像丶邮箱丶基本信息)
  • 我的课程
  • 我的收藏(取消收藏)
  • 我的消息

8.全局功能

  • 搜索功能(公开课丶课程机构丶授课老师)
  • 全局404和500页面配置
  • 首页开发
  • 点击数和收藏数修改以及退出功能

9.web攻击及防范

  • sql注入攻击
  • xss攻击
  • csrf攻击

10.xadmin进阶开发

  • userprofile注册和设置
  • xadmin常见功能设置
  • inlinemode注册和proxy代理注册
  • django ueditor富文本编辑器集成
  • excel导入插件集成

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_745163.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Django与Elasticsearch交互打造搜索引擎网站(一)

说明&#xff1a;该篇博客是博主一字一码编写的&#xff0c;实属不易&#xff0c;请尊重原创&#xff0c;谢谢大家&#xff01; 项目源码下载 目录 一丶叙述 二丶elasticsearch-rtf的安装与测试 三丶elasticsearch-head插件以及kibana的安装 四丶elasticsearch搜索引擎的使…

2020 搭建一个属于自己的动态网站(WordPress+云服务器BCC)

说明&#xff1a;该篇博客是博主一字一码编写的&#xff0c;实属不易&#xff0c;请尊重原创&#xff0c;谢谢大家&#xff01; 文章目录前言一、WordPress是什么&#xff1f;二、建站准备1.准备服务器2.准备域名三、网站搭建1.安装宝塔面板2.宝塔面板搭建站点3.域名解析4.通过…

2021 搭建一个属于自己的静态网站(Hexo+GitHub Pages)

说明&#xff1a;该篇博客是博主一字一码编写的&#xff0c;实属不易&#xff0c;请尊重原创&#xff0c;谢谢大家&#xff01; 文章目录前言一、Hexo是什么&#xff1f;二、GitHub Pages是什么&#xff1f;三、建站准备1.准备Github账号2.准备域名四、网站搭建1. 安装 Node.js…

2021 WordPress 网站迁移(从百度云BCC 迁移到 阿里云ECS)

说明&#xff1a;该篇博客是博主一字一码编写的&#xff0c;实属不易&#xff0c;请尊重原创&#xff0c;谢谢大家&#xff01; 文章目录前言一、迁移准备1. 备份原网站2. 备份数据库3. 准备服务器4. 准备好域名5. ICP域名备案二、网站迁移1. ICP备案成功2. 安装宝塔面板3. 创建…

网站架构基础学习(详细)

网站架构基础学习(详细) 1.网站架构的发展经历: 初始阶段的网站(特点&#xff1a;没人)应用程序&#xff0c;数据库&#xff0c;文件都在一个服务器中 比如我们学的是开发&#xff0c;我们要写一个网站&#xff0c;因为这是一个项目&#xff0c; 所以我们要把它部署一下&#x…

云服务器怎么显示网站数据库名称,云服务器怎么显示网站数据库

云服务器怎么显示网站数据库 内容精选换一换本章节指导您使用MongoDB客户端&#xff0c;通过弹性云服务器内网方式连接GaussDB(for Mongo)集群实例。操作系统使用场景&#xff1a;弹性云服务器的操作系统以Linux为例&#xff0c;客户端本地使用的计算机系统以Windows为例。目标…

给自己的网站带来和平:实现自动开启Cloudflare的5秒盾和验证码

引言 梦也不分明&#xff0c;远山云乱横。 ——勿埋我心 你的网站有没有被攻击过&#xff1f;这个脚本虽然不能抵御那些恐怖的“洪流”&#xff0c;但是抵挡一下“小打小闹”应该问题不大。   原理&#xff1a;通过检测系统负载&#xff08;cpu或load&#xff09;自动开启clo…

过滤器的使用实现网站访问计数器

随时随地阅读更多技术实战干货&#xff0c;获取项目源码、学习资料&#xff0c;请关注源代码社区公众号(ydmsq666) 一、创建过滤器需要使用javax.servlet.Filter接口&#xff0c;同时实现Filter接口的3个方法。 CountFilter: package com.home.web;import java.io.IOException…

Nginx配置SSL证书部署HTTPS网站(颁发证书)

自行颁发不受浏览器信任的SSL证书 手动颁发 xshell登录服务器&#xff0c;使用openssl生成RSA密钥及证书 # 生成一个RSA密钥 $ openssl genrsa -des3 -out tfjybj.key 1024# 拷贝一个不需要输入密码的密钥文件 $ openssl rsa -in dmsdbj.key -out tfjybj_nopass.key# 生成一…

实战学习NodeJS建站(5)—nodejs 访问 redis

随时随地阅读更多技术实战干货&#xff0c;获取项目源码、学习资料&#xff0c;请关注源代码社区公众号(ydmsq666) from&#xff1a;http://blog.csdn.net/qidong7/article/details/52888211 前提是你已经安装了nodejs环境。 node_redis是nodejs访问redis的客户端安装包&…

excel修改列名_利用Excel分析招聘网站数据分析师岗位

Excel是进行数据分析用得最多、最基本的工具&#xff0c;下面内容是运用Excel2013对一份数据分析师招聘网站的数据进行分析。Excel数据分析的步骤&#xff1a;1、提出问题&#xff08;明确数据分析目的&#xff09;2、理解数据&#xff08;理解数据列名的意义&#xff09;3、数…

图片变色_『设计|分享』设计师的色彩网站推荐(一)—渐变色

整理&#xff1a;设计与设计师&#xff08;ID&#xff1a;Design-Designer&#xff09;作者&#xff1a;设计与设计师转载请注明出处。配色对一项设计的重要性&#xff0c;这边就不多加赘述。在色彩设计应用中&#xff0c;我们对颜色不同程度的理解&#xff0c;将影响到产品&am…

php写伪静态,php网站动态网站的伪静态写法

PHP网站是主要是以动态网页展示&#xff0c;有时候为了方便优化&#xff0c;也可以设置伪静态来进行网站的优化。主要是通过下面的方式进行伪静态的书写&#xff1a;首先我们先查看Apache是否支持mod_rewrite功能&#xff0c;可以通过PHP提供的phpinfo()函数查看是否支持重写功…

ab压力测试_使用ab命令对网站进行压力测试

概述这是apache自带的一个网站压力测试工具&#xff0c;是ApacheBench的缩写&#xff0c;我们可以使用这个工具来对我们的网站进行压力测试安装在ubuntu上要安装下面这个包sudo apt-get install apache2-utils在centos下是下面这个包sudo yum install httpd-tools -y使用可以直…

虾米音乐java_抓取虾米音乐网站音乐,搜索虾米音乐功能的java实现

可以实现和点点网音乐分享功能暂时还没做界面&#xff0c;先留下代码package com;/*** 歌曲实体* author hanfei**/public class Song {private String title;private String songUrl;private String flashUrl;private String image;public String getTitle() {return title;}p…

百度二级网页打不开_网站降权都是什么原因 - 百度蜘蛛池博客

原出处&#xff1a;蜘蛛池博客原文链接&#xff1a;网站降权都是什么原因&#xff1f; - 蜘蛛池博客我们要学会找出网站降权的原因&#xff0c;才能知道如何对症下药&#xff0c;解决问题。那么&#xff0c;网站降权都是什么原因&#xff1f;接下来蜘蛛池博客小编就跟大家介绍几…

oracle表空间状态如何离线,read/write - Oracle表空间的状态_数据库技术_Linux公社-Linux系统门户网站...

表空间状态-READ ONLY、READ WRITE1. 只读表空间的主要用途就是为了消除对数据库大部分静态数据的备份和恢复的需要。Oracle不会更新只读表空间爱你的文件&#xff0c;因此这部分文件可以存储于只读介质中&#xff0c;例如CD-ROM或WORM drives。2. 只读表空间并不是为了满足归档…

计算机违反网络策略该怎么弄,网络策略设置禁止您使用该网站获取您计算机的更新程序。怎么办?...

进入微软windows update网站提示&#xff1a;网络策略设置禁止您使用该网站获取您计算机的更新程序。如果您确认此消息有误,请向您的系统管理员咨询。本人找到的是在 组策略(打开方法 运行&#xff0d;>gpedit.msc)->计算机配置->管理模板->windows组件->window…

基于php网上购物商城用例图,动漫周边电商网站的设计与实现(PHP,MySQL)(含录像)...

动漫周边电商网站的设计与实现(PHP,MySQL)(含录像)(毕业论文10000字,程序代码,MySQL数据库)摘要本商品电商网站是为了方面用户在线购物而设计开发的商品电商网站&#xff0c;其开发过程主要包括前端应用程序的开发和后台数据库的建立和维护两个方面。本网站的开发可以在网上进行…

网站备案服务器ip怎么填写,域名备案网站ip地址如何填写

域名备案网站ip地址如何填写 内容精选换一换依据《非经营性互联网信息服务备案管理办法》第十四条、第二十三条规定&#xff0c;如备案信息不真实&#xff0c;将关闭网站并注销备案。若您的备案信息发生变更&#xff0c;请您提前三十日申请变更备案。对于已备案网站仅对应一个域…