Django前後端分離開發-新聞管理系統(五)

項目源碼下載:https://github.com/Cherish-sun/NEWS/tree/master

前端系統架構圖

前後端系統架構圖

一、創建前端項目和應用

django-admin.py startproject newsapi
python manage.py startapp article

將static和templates文件夾拷貝到我們的項目中。
並在setting的APP裏,添加article

INSTALLED_APPS = [
    ...
    'artcile',
]

setting裏添加 配置靜態文件

STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static').replace('', '/')
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)

web前端的工作原理是,請求後端對應的url,對url進行解析,傳給html模板,返回給瀏覽器(用戶)

1.基本方法-urlopen

urllib.request.urlopen(url,data=None, [timeout, ]*, cafile=None, capath=None, cadefault=False, context=None)

  • url: 需要打開的網址
  • data:Post提交的數據
  • timeout:設置網站的訪問超時時間
    直接用urllib.request模塊的urlopen()獲取頁面,page的數據格式爲bytes類型,需要decode()解碼,轉換成str類型。
    from urllib import request
    response = request.urlopen(r’http://python.org/’) # <http.client.HTTPResponse object at 0x00000000048BC908> HTTPResponse類型
    page = response.read()
    page = page.decode(‘utf-8’)
    urlopen返回對象提供方法:
  • read() , readline() ,readlines() , fileno() , close() :對HTTPResponse類型數據進行操作
  • info():返回HTTPMessage對象,表示遠程服務器返回的頭信息
  • getcode():返回Http狀態碼。如果是http請求,200請求成功完成;404網址未找到
  • geturl():返回請求的url
2.使用Request

urllib.request.Request(url,data=None, headers={}, method=None)
使用request()來包裝請求,再通過urlopen()獲取頁面。
url = r’http://www.lagou.com/zhaopin/Python/?labelWords=label’
headers = {
‘User-Agent’: r’Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ’
r’Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3’,
‘Referer’: r’http://www.lagou.com/zhaopin/Python/?labelWords=label’,
‘Connection’: ‘keep-alive’ }
req = request.Request(url, headers=headers)
page = request.urlopen(req).read()
page = page.decode(‘utf-8’)
用來包裝頭部的數據:

  • User-Agent :這個頭部可以攜帶如下幾條信息:瀏覽器名和版本號、操作系統名和版本號、默認語言
  • Referer:可以用來防止盜鏈,有一些網站圖片顯示來源http://***.com,就是檢查Referer來鑑定的
  • Connection:表示連接狀態,記錄Session的狀態。

二、views.py

1、導入包

from urllib import request, parse

try:
    import json
except ImportError:
    import simplejson as json
from django.shortcuts import render
from urllib.parse import urljoin

# Create your views here.

PAGESIZE = 5

2、引入所有API

category_url = 'http://127.0.0.1:8005/category/'
articles_url = 'http://127.0.0.1:8005/articleList/'
hotarticles_url = 'http://127.0.0.1:8005/hot_articleList/'
ad_url = 'http://127.0.0.1:8005/ad/'
items_url = 'http://127.0.0.1:8005/item/'

3、定義公用獲取解析API方法

# 讀取api數據
def getdata(url, data=None):
    # url = r'http://xxx/xxx/xxxx?'
    headers = {
        'User-Agent': r'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) '
                  r'Chrome/45.0.2454.85 Safari/537.36 115Browser/6.0.3',
        'Referer': r'',
        'Connection': 'keep-alive',
        'Content-Type': 'application/json',
        'Access-Control-Allow-Origin': '*',
    }
    # data = {
    #     'first': 'true',
    #     'pn': 1,
    #     'kd': 'Python'
    #     }
    # urlencode()主要作用就是將url附上要提交的數據。
    # 經過urlencode()轉換後的data數據爲?first=true?pn=1?kd=Python,最後提交的url爲
    # http://xxxxx/xx/xx?first=true?pn=1?kd=Python
    try:
        if data:
            # data = parse.urlencode(data).encode('utf8')
            # data 參數如果要傳必須傳 bytes (字節流)類型的,如果是一個字典,可以先用 urllib.parse.urlencode() 編碼。
            # data = bytes(parse.urlencode(data), encoding="utf8")
            data = '?' + parse.urlencode(data)
            # 使用request()來包裝請求,再通過urlopen()獲取頁面。
            url = urljoin(url, data)
            req = request.Request(url=url, headers=headers, method='GET')
        else:
            req = request.Request(url=url, headers=headers)

        reponsedata = request.urlopen(req, timeout=10).read()
        reponsedata = reponsedata.decode('utf-8')
        returndata = json.loads(reponsedata)
    except Exception as e:
        print(e)
        returndata = {'result': e, 'code': e, 'msg': '請求api數據錯誤!', 'data': '{}', 'redirect_url': ''}
    return returndata

4、新聞分類、熱門新聞、廣告定義成全局變量,分別調用getdata函數
全局變量

# 實現全局變量
def globl_init(request):
    # 取新聞分類
    # #category_list = Category.objects.all()
    category_list = getdata(category_url)
    # 取熱門新聞
    # hot_articles = Article.objects.filter(is_active=True)[0:5]
    hot_articles = getdata(hotarticles_url)
    # 取廣告數據
    ad_list = getdata(ad_url)
    user = request.user
    return locals()

全局變量要想在每個頁面都生效,必須配置setting裏

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',
                'artcile.views.globl_init', # 新增
            ],
        },
    },
]

5、實現首頁功能

def index(request):
    data = {
        "ordering": '-id',
    }
    article_data = getdata(articles_url, data)
    article_list = article_data["results"]

    user = []
    return render(request, 'index.html', locals())
# 文章詳情頁
def article(request):
    pass

# 搜索
def search(request):
    pass    


# 分類頁
def category(request):
    pass
locals作用:不需要把結果(article_list )封裝成上下文、local()自動將將結果作爲上下文數據,並渲染到模板裏

6、模板文件index.html

index.html繼承了及基礎base.html文件,基礎文件包括欄目導航、內容部分(包括左邊輪播,左邊新聞列表、右邊廣告、右邊熱門新聞、右邊廣告、右邊關注我們)、頁腳部分

{% load staticfiles %}
{% load dictfilter %}
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<title></title>
<meta name="keywords" content="" />
<meta name="description" content="" />
<link href="{% static 'css/base.css' %}" rel="stylesheet">
{% block custom_css %}{% endblock %}
<script type="text/javascript" src="{% static 'js/jquery-1.11.1.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/slide.js' %}"></script>
<script type="text/javascript" src="{% static 'js/jquery.cookie.js' %}"></script>
{% block custom_js %}{% endblock %}

</head>
<body>
  <!--欄目導航-->
<div class="header">
    <div class="layout logo">
        <a href="http://www.careeru.cn/" class="logoimg"><img src="/static/images/careeru.png" class="logoimg"></a>
        <ul class="nav">
            <li class="cur"><a href="/">首頁</a></li>
           {% for category in category_list %}
                {% if category|key:"id" == categoryid %}
                   <li class="columnnav  cur">
                {% else %}
                   <li class="columnnav">
                {% endif %}
                     <a href="{% url 'category' %}?cid={{category|key:"id" }}">{{category|key:"title" }}</a>
                   </li>

           {% endfor %}

        </ul>
        <div  class="userlogin">
           <div  id="logined" style="display: none">
             <span id="navlogout"><a href="javascript:void(0)">註銷</a></span>
             <span id="navprofile"></span>
          </div>
          <div  id="nologin">
              <span id="navregister"><a class="curegister" href="javascript:;">註冊</a></span>
              <span id="navlogin"><a class="ulogin" href="javascript:;" data-status="nologin">登錄</a>    </span>
          </div>
     </div>
        <form  action="{% url 'search' %}" id="Search" name="search_box" method="get" target="_blank" >
            <input id="searchKey" title="請輸入關鍵詞" name="query"  autocomplete="off"  type="text">
            <input id="searchBtn" value=""  onclick="" aria-pressed="false" type="submit">
        </form>

    </div>
</div>
<!--內容部分-->
 <div class="layout">
      <!--左邊部分-->
     {% with  ads=ad_list %}
      <div class="main">
          <!--左邊輪播廣告部分-->
          <div  class="ad">
                <div class="ad-inner ">
                    <div class="item active">
                          <!--廣告大圖片-->
                        <ul class="slidebox" id="" style="display: block;">
                            <div class="ad_slide">
                                    <ul id="slidelist" class="slideshow">
                                        {% for ad in ads %}

                                            <li style="display: block;">
                                                <a href="{{ ad.adurl }}" target="_blank" class="ad_imga">
                                                    <img src="{{ ad.pic }}"  width="880" height="300"></a>
                                            </li>
                                        {% endfor %}
                                    </ul>

                             </div>
                        </ul>
                    </div>
                </div>
          </div>
          <!--左邊新聞列表部分-->
          {% block left_content %}{% endblock %}
      </div>
      <!--右邊部分-->
      <div class="side">
          <!--廣告-->
        <div class="author_ad ad_div">
                    <div  class="ad slide">
                            <div class="ad-inner star_div">
                                 {% for ad in ads %}
                                        {% if ad.adlocation == 'a2' %}
                                            <div class="item active">
                                                <a href="{{ ad.adurl }}" target="_blank">
                                                    <img src="{{ ad.pic }}" alt="" style="width:300px;height:300px;">
                                                </a>
                                            </div>
                                        {% endif %}
                                 {% endfor %}
                             </div>
                    </div>
        </div>
        <!--熱門新聞-->

        <div class="hot module">
          <h3 class="subtitle">熱門新聞</h3>
            <ul  class="article_lists">
                {% for hotactile in hot_articles %}
                  <li>
                     <i class="top3">{{ forloop.counter }}</i>
                     <a href="{% url 'article' %}?id={{ hotactile.id }}">{{ hotactile.title | slice:'15'}}</a>
                  </li>
                {% endfor %}

            </ul>
        </div>

        <!--廣告-->
        <div class="ad2">
           <ul>
                {% for ad in ads %}
                     {% if ad.adlocation == 'a3' %}
                       <a href="{{ ad.adurl }}" target="_blank">
                         <li><img src="{{ ad.pic }}" width="300" ></li>
                       </a>
                      {% endif %}
                {% endfor %}
          </ul>
        </div>
        <!--關注我們-->
        <div class="follow">
         <div class="subtitle">關注我們</div>
          <div class="side_list">
             <img src="/static/images/careerqq0.8.png" >
          </div>

          <!--ms-main end -->
        </div>
      </div>
      {% endwith %}
      {%include 'loginlayer.html' %}
</div>
  <!--頁腳部分-->
<footer>
  <p class="ft-copyright"></p>
 <div role="contentinfo" bosszone="footer" class="tcopyright" id="tcopyright">

    <div class="en">Copyright &copy; 2010- 2018 Careeru.cn All Rights Reserved</div>
    <div>
        <a rel="nofollow" target="_blank" href="/">可銳職場出品</a>
    </div>
</div>
</footer>
<script type="text/javascript">
   if ($.cookie('user')) {
       $('#nologin').css('display', 'none');
       $('#logined').css('display', 'block');
       $('#navprofile').html($.cookie('user'));
   };
</script>
</body>
</html>

我們看下欄目導航

 <ul class="nav">
        <li class="cur"><a href="/">首頁</a></li>
       {% for category in category_list %}
            {% if category|key:"id" == categoryid %}
               <li class="columnnav  cur">
            {% else %}
               <li class="columnnav">
            {% endif %}
                 <a href="{% url 'category' %}?cid={{category|key:"id" }}">{{category|key:"title" }}</a>
               </li>
       {% endfor %}
    </ul>

首先取出分類數據,由於category_list數據是字典,我們需要寫一個過濾器。
在article同級目錄下新建python包命名爲templatetags,在裏面新建python文件命名爲dictfilter.py

from django import template

register = template.Library()
@register.filter
def key(d, key_name):
    value = 0
    try:
        value = d[key_name]
    except KeyError:
        value = 0
    return value

這裏我們往key裏傳入一個字典和一個鍵名,就能取出相應的值。
那麼在index.html只需要寫左邊新聞列表部分

{% extends 'base.html' %}
{% load staticfiles %}
{% block left_content %}
    <div class="article_div module">
        <ul id="new_div">
        {% if  article_list %}
          {% for article in article_list %}
              <li class="news">
                <div>
                    <div class="flag">推薦</div>
                    <a href="{% url 'article' %}?id={{ article.id }}" target="_blank">
                    <img  src="{{ article.pic }} " class="pic"></a>
                    <div class="detail">
                        <div class="dtitle">
                            <a  href="{% url 'article' %}?id={{ article.id }}" target="_blank"><h2>{{ article.id }}-{{ article.title }}</h2></a>
                        </div>
                        <div class="desc">{{ article.content|striptags|safe|slice:"80" }}</div>
                        <div class="info">
                            <img src="/static/images/neter.jpg" class="img_small"><span>{{ article.author.username }}</span>
                            <div class="pv">
                               <span class="push-time">{{ article.publish_date |date:"Y-m-d H:i:s"}}</span><span class="column">
                               <a href="/">{{ article.item.title }}</a>&nbsp;</span>
                            </div>
                        </div>
                    </div>
                </div>
            </li>
           {% endfor %}
        {% else %}
         <div><img style="width:200px;padding-left:280px; " src="/static/images/nodata1.png"></div>
        {% endif %}
         </ul>
    </div>
    {% include 'page.html' %}
{% endblock %}

7、配置urls

from django.contrib import admin
from django.urls import path, re_path
from artcile.views import *

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path(r'^$', index, name='index'),
    path('category/', category, name='category'),
    path('article/', article, name='article'),
    path('search/', search, name='search'),
  ]

這時打開瀏覽器:http://127.0.0.1:8000 就可以看到新聞類別、新聞列表、廣告、輪播圖、熱門新聞、關注我們。
效果圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章