zoukankan      html  css  js  c++  java
  • (项目)在线教育平台(十二)

    十七、首页和全局404、500页面配置

    1、首页配置

      首页页面轮播课程需要在课程的model中添加is_banner字段,说明是否是轮播课程:

     1 class Course(models.Model):
     2     """课程"""
     3     DEGREE_CHOICES = (
     4         ('cj', '初级'),
     5         ('zj', '中级'),
     6         ('gj', '高级')
     7     )
     8 
     9     name = models.CharField('课程名', max_length=50)
    10     desc = models.CharField('课程描述', max_length=300)
    11     detail = models.TextField('课程详情')
    12     degree = models.CharField('课程难度', choices=DEGREE_CHOICES, max_length=2)
    13     learn_times = models.IntegerField('学习时长(分钟数)', default=0)
    14     students = models.IntegerField('学习人数', default=0)
    15     fav_nums = models.IntegerField('收藏人数', default=0)
    16     click_nums = models.IntegerField('点击数', default=0)
    17     image = models.ImageField('封面图', upload_to='courses/%Y/%m', max_length=100)
    18     course_org = models.ForeignKey(CourseOrg, verbose_name='所属机构', on_delete=models.CASCADE, null=True, blank=True)
    19     category = models.CharField('课程类别', max_length=20, default='')
    20     tag = models.CharField('标签', max_length=10, default='')
    21     teacher = models.ForeignKey(Teacher, verbose_name='机构讲师', on_delete=models.CASCADE, null=True, blank=True)
    22     courseneed_know = models.CharField('课程须知', max_length=300, default='')
    23     teacher_tellyou = models.CharField('老师告诉你', max_length=300, default='')
    24     is_banner = models.BooleanField('是否轮播', default=False)
    25     add_time = models.DateTimeField('添加时间', default=datetime.now)
    26 
    27     class Meta:
    28         verbose_name = '课程'
    29         verbose_name_plural = verbose_name
    30 
    31     # 获取章节数
    32     def get_zj_nums(self):
    33         return self.lesson_set.all().count()
    34 
    35     # 获取学习用户
    36     def get_learn_users(self):
    37         return self.usercourse_set.all()[:5]
    38 
    39     # 获取章节
    40     def get_course_lesson(self):
    41         return self.lesson_set.all()
    42 
    43     def __str__(self):
    44         return self.name

      机构显示需要机构标签,在机构的model中添加tag字段:

     1 class CourseOrg(models.Model):
     2     """课程机构"""
     3     CATEGORY_CHOICES = (
     4         ('pxjg', '培训机构'),
     5         ('gx', '高校'),
     6         ('gr', '个人')
     7     )
     8     name = models.CharField('机构名称', max_length=50)
     9     category = models.CharField('机构类别', max_length=20, choices=CATEGORY_CHOICES, default='pxjg')
    10     desc = models.TextField('机构描述')
    11     students = models.IntegerField('学习人数', default=0)
    12     course_nums = models.IntegerField('课程数', default=0)
    13     click_nums = models.IntegerField('点击数', default=0)
    14     fav_nums = models.IntegerField('收藏数', default=0)
    15     image = models.ImageField('封面图', upload_to='org/%Y/%m', max_length=100)
    16     address = models.CharField('地址', max_length=150)
    17     city = models.ForeignKey(CityDict, verbose_name='所在城市', on_delete=models.CASCADE)
    18     tag = models.CharField('机构标签', max_length=10, default='全国知名')
    19     add_time = models.DateTimeField('添加时间', default=datetime.now)
    20 
    21     class Meta:
    22         verbose_name = '课程机构'
    23         verbose_name_plural = verbose_name
    24 
    25     # 获取教师数量
    26     def get_teacher_nums(self):
    27         return self.teacher_set.all().count()
    28 
    29     def __str__(self):
    30         return self.name

      迁移数据库。

      首页的数据都是需要从后台获取的,先编写首页的接口:

     1 class IndexView(View):
     2     """首页"""
     3     def get(self, request):
     4         # 轮播图
     5         all_banners = Banner.objects.all().order_by('index')
     6 
     7         # 课程
     8         courses = Course.objects.filter(is_banner=False)[:6]
     9         # 轮播课程
    10         banner_courses = Course.objects.filter(is_banner=True)[:3]
    11 
    12         # 机构
    13         orgs = CourseOrg.objects.all()[:15]
    14         return render(request, 'index.html', {
    15             'all_banners': all_banners,
    16             'courses': courses,
    17             'banner_courses': banner_courses,
    18             'orgs': orgs
    19         })

      然后修改首页的url:

    1 urlpatterns = [
    2     path('', IndexView.as_view(), name='index'),  # 首页
    3 ]

      修改前端首页页面中显示数据的代码:

      1 {% extends 'base.html' %}
      2 
      3 {% load staticfiles %}
      4 
      5 {% block title %}
      6     知能网 - 首页
      7 {% endblock %}
      8 
      9 {% block content %}
     10     <div class="banner">
     11             <div class="wp">
     12                 <div class="fl">
     13                     <div class="imgslide">
     14                         <ul class="imgs">
     15 {#                        遍历显示轮播图#}
     16                             {% for banner in all_banners %}
     17                                 <li>
     18                                     <a href="{{ banner.url }}">
     19                                         <img width="1200" height="478" src="{{ MEDIA_URL }}{{ banner.image }}" />
     20                                     </a>
     21                                 </li>
     22                             {% endfor %}
     23                         </ul>
     24                     </div>
     25                     <div class="unslider-arrow prev"></div>
     26                     <div class="unslider-arrow next"></div>
     27                 </div>
     28 
     29                 </div>
     30 
     31 
     32             </div>
     33 <!--banner end-->
     34 <!--feature start-->
     35     <section>
     36         <div class="wp">
     37             <ul class="feature">
     38                 <li class="feature1">
     39                     <img class="pic" src="/static/images/feature1.png"/>
     40                     <p class="center">专业权威</p>
     41                 </li>
     42                 <li class="feature2">
     43                     <img class="pic" src="/static/images/feature2.png"/>
     44                     <p class="center">课程最新</p>
     45                 </li>
     46                 <li class="feature3">
     47                     <img class="pic" src="/static/images/feature3.png"/>
     48                     <p class="center">名师授课</p>
     49                 </li>
     50                 <li class="feature4">
     51                     <img class="pic" src="/static/images/feature4.png"/>
     52                     <p class="center">数据真实</p>
     53                 </li>
     54             </ul>
     55         </div>
     56     </section>
     57 <!--feature end-->
     58 <!--module1 start-->
     59     <section>
     60         <div class="module">
     61             <div class="wp">
     62                 <h1>公开课程</h1>
     63                 <div class="module1 eachmod">
     64                     <div class="module1_1 left">
     65                         <img width="228" height="614" src="/static/images/module1_1.jpg"/>
     66                         <p class="fisrt_word">名师授课<br/>专业权威</p>
     67                         <a class="more" href="{% url 'course:course_list' %}">查看更多课程 ></a>
     68                     </div>
     69                     <div class="right group_list">
     70                         <div class="module1_2 box">
     71                             <div class="imgslide2">
     72                                 <ul class="imgs">
     73 {#                                遍历显示轮播课程#}
     74                                     {% for banner_course in banner_courses %}
     75                                         <li>
     76                                         <a href="{% url 'course:course_detail' banner_course.id %}">
     77                                             <img width="470" height="300" src="{{ MEDIA_URL }}{{ banner_course.image }}" />
     78                                         </a>
     79                                     </li>
     80                                     {% endfor %}
     81                                 </ul>
     82                             </div>
     83                             <div class="unslider-arrow2 prev"></div>
     84                             <div class="unslider-arrow2 next"></div>
     85                         </div>
     86 {#                        遍历显示课程#}
     87                             {% for course in courses %}
     88                                 <div class="module1_{{ forloop.counter|add:2 }} box">
     89                                 <a href="{% url 'course:course_detail' course.id %}">
     90                                     <img width="233" height="190" src="{{ MEDIA_URL }}{{ course.image }}"/>
     91                                 </a>
     92                                 <div class="des">
     93                                     <a href="{% url 'course:course_detail' course.id %}">
     94                                         <h2 title="{{ course.name }}">{{ course.name }}</h2>
     95                                     </a>
     96                                     <span class="fl">难度:<i class="key">{{ course.get_degree_display }}</i></span>
     97                                     <span class="fr">学习人数:{{ course.students }}</span>
     98                                 </div>
     99                                 <div class="bottom">
    100                                     <span class="fl" title="慕课网">{{ course.course_org.name }}</span>
    101                                     <span class="star fr">{{ course.fav_nums }}</span>
    102                                 </div>
    103                             </div>
    104                             {% endfor %}
    105                     </div>
    106                 </div>
    107             </div>
    108         </div>
    109     </section>
    110     <section>
    111         <div class="module greybg">
    112             <div class="wp">
    113                 <h1>课程机构</h1>
    114                 <div class="module3 eachmod">
    115                     <div class="module3_1 left">
    116                         <img width="228" height="463" src="/static/images/module3_1.jpg"/>
    117                         <p class="fisrt_word">名校来袭<br/>权威认证</p>
    118                         <a class="more" href="{% url 'org:org_list' %}">查看更多机构 ></a>
    119                     </div>
    120                     <div class="right">
    121                         <ul>
    122 {#                        遍历显示机构#}
    123                             {% for org in orgs %}
    124                                 <li class="{% if forloop.counter|divisibleby:5 %}five{% endif %}">
    125                                     <a href="{% url 'org:org_home' org.id %}">
    126                                         <div class="company">
    127                                             <img width="184" height="100" src="{{ MEDIA_URL }}{{ org.image }}"/>
    128                                             <div class="score">
    129                                                 <div class="circle">
    130                                                     <h2>{{ org.tag }}</h2>
    131                                                 </div>
    132                                             </div>
    133                                         </div>
    134                                         <p><span class="key" title="{{ org.name }}">{{ org.name }}</span></p>
    135                                     </a>
    136                                 </li>
    137                             {% endfor %}
    138                         </ul>
    139                     </div>
    140                 </div>
    141             </div>
    142         </div>
    143     </section>
    144 {% endblock %}
    145 
    146 {% block custom_js %}
    147     <script type="text/javascript" src="/static/js/index.js"></script>
    148 {% endblock %}
    index.html

      我们在登出然后登陆之后发现轮播图的数据不见了,需要修改登录接口中render首页的代码:

     1 class LoginView(View):
     2     """登录"""
     3     def get(self, request):
     4         return render(request, 'login.html')
     5 
     6     def post(self, request):
     7         # form实例化
     8         login_form = LoginForm(request.POST)
     9         if login_form.is_valid():
    10             # form验证通过,获取用户提交的用户名和密码
    11             user_name = request.POST.get('username', None)
    12             pass_word = request.POST.get('password', None)
    13 
    14             # 通过django的authenticate方法获取user对象,也就是验证用户是否存在
    15             user = authenticate(username=user_name, password=pass_word)
    16 
    17             if user is not None:
    18                 if user.is_active:
    19                     # 只有激活用户才能登录
    20                     # 验证通过,通过django的login方法去登录,然后返回首页
    21                     login(request, user)
    22                     return HttpResponseRedirect(reverse('index'))
    23                 else:
    24                     # 验证不通过,返回登录页面,并将错误信息返回去显示
    25                     return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form})
    26             else:
    27                 # 验证不通过,返回登录页面,并将错误信息返回去显示
    28                 return render(request, 'login.html', {'msg': '用户名或密码错误', 'login_form': login_form})
    29         else:
    30             return render(request, 'login.html', {'login_form': login_form})

    2、404、500页面配置

      404、500页面,必须在setting.py中设置DEBUG = False:

    1 DEBUG = False
    2 
    3 ALLOWED_HOSTS = ['*']
    4 
    5 # 静态文件
    6 STATIC_URL = '/static/'
    7 STATIC_ROOT = os.path.join(BASE_DIR, 'static')

      在设置DEBUG = False后,django就不会代管你的静态文件,所以要在urls.py文件中设置url处理静态文件的url:

    1 urlpatterns = [
    2     re_path(r'^static/(?P<path>.*)', serve, {"document_root": STATIC_ROOT}),  # 静态文件显示
    3 ]

      然后将404、500页面的html文件放到templates下即可配置完成。

    十八、常见的web攻击与防护

    1、sql注入攻击与防护

    1.1 sql注入攻击的危害

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

    1.2 SQL注入攻击原理

      比如下面一段代码:

     1 class LoginUnsafeView(View):
     2     def get(self, request):
     3         return render(request, "login.html", {})
     4     def post(self, request):
     5         user_name = request.POST.get("username", "")
     6         pass_word = request.POST.get("password", "")
     7 
     8         import MySQLdb
     9         conn = MySQLdb.connect(host='127.0.0.1', user='root', passwd='root', db='mxonline', charset='utf8')
    10         cursor = conn.cursor()
    11         sql_select = "select * from users_userprofile where email='{0}' and password='{1}'".format(user_name, pass_word)
    12 
    13         result = cursor.execute(sql_select)
    14         for row in cursor.fetchall():
    15             # 查询到用户
    16             pass
    17         print 'test'

      用户在登录的时候用户名如果输入 ' OR 1=1, 密码随便输入,SQL语句就变成了这样:

      select * from users_userprofile where email='' OR 1=1' and password='123',email='' or 1=1这条件就直接为True了,不用去执行后面的and语句了,那么是不是直接就将用户的信息拿到了呢,所以这种写法是非常危险的。

      那么如何去防护呢?可以尽量不去使用SQL原生语句去获取数据,可以通过django的orm去查询数据,在登录的使用使用django的login函数,这个函数是安全的。

    2、xss攻击与防护

    2.1 xss跨站脚本攻击的危害

    • 控制受害者机器向其他网站发起攻击,注入木马
    • 盗取各类用户账号
    • 非法转账等

    2.2 xss攻击原理

      黑客将一段带有js代码的url发送给用户,用户点击这个url后发送请求到服务器,服务器返回数据给受害者,然后浏览器执行这段js脚本将用户的cookie信息发送给黑客,然后黑客拿着用户的cookie伪装成用户向服务器发送请求,这时黑客就可以进行任何攻击或者其他操作。

    2.3 xss防护

    • 对用户输入的地方和变量都检查长度和对<>;'等字符做一些过滤
    • 不要在cookie中泄露用户的隐私数据,如用户名和密码
    • 将cookie和系统ip绑定来降低cookie泄露后的危险
    • 尽量采用POST方法而非GET提交表单

    3、csrf攻击与防护

    2.1 csrf攻击的危害

    • 以用户的名义去发送邮件
    • 盗取账号
    • 购买商品
    • 虚拟货币转账

    2.2 csrf攻击的原理

      用户登录受信任的A服务器,服务器返回cookie,用户之后的每次请求都会带上cookie去访问A服务器,但是用户在同时的时候没有登出或者关闭A服务器的页面,直接去访问危险的B服务器,然后B服务器要求用户去访问A的一个url,这时信息就会泄露。

    2.3 csrf攻击的防护

      在每个form中加上{{ csrf_token }}即可

  • 相关阅读:
    python 执行sql得到字典格式数据
    python爬虫 url链接编码成gbk2312格式
    windows环境下elasticsearch安装教程(单节点)
    python SQLServer 存储图片
    爬虫的本质是和分布式爬虫的关系
    requests form data 请求 爬虫
    mysql 删除 binlog 日志文件
    查看mysql数据表的大小
    xshell 连接报错 Disconnected from remote host
    centos 7.3 安装 mysqldb 报错 EnvironmentError: mysql_config not found ERROR: Command errored out with exit status 1: python setup.py egg_info Check the logs for full command output.
  • 原文地址:https://www.cnblogs.com/Sweltering/p/10004640.html
Copyright © 2011-2022 走看看