08のHelloDjango:ブログの記事の詳細ページを開発


著者:HelloGitHub- ドリームフィギュア

サンプルコードは、テキストに関連する、同期するように更新されていHelloGitHub-チームの倉庫を

ホームは、ユーザーが興味のある記事を見たとき、彼は記事のタイトルをクリックするか、記事の詳細を表示する記事の詳細ページにジャンプしなければならないボタンを読み続け、すべての記事の一覧を表示します。今度は、ベースの前で、ブログの詳細ページを発展させ、開発プロセスは同じです:最初に設定されたURLが、それは一緒に関連するURLとビュー機能を結合し、その後、ビュー機能を実装して、テンプレートを記述してみましょうすることですビューテンプレートのレンダリング機能。

デザインの記事ページのURLの詳細

ブログの\ urls.pyファイルで、私たちのホームページのURLビューを思い出して、私たちは書きました:

blog/urls.py

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]

ドメイン名を除去した後URLホームビューの試合は、実際には空の文字列です。詳細は、記事を表示するために、各記事は、別​​のURLに対応しています。たとえば、私たちはこのように見えるように設計された、対応する記事の詳細ページを表示することができます。ユーザーがアクセスすると、<ドメイン> /ポスト/ 1 /、最初の記事の内容の表示、およびユーザーの訪問<ドメイン> /投稿/ 2 /、最初の数はいくつかの記事、データベースポストレコード内、すなわちID値を表す第二物品のコンテンツの表示。URLやビューをバインドするには、次の規則に従って:

blog/urls.py

from django.urls import path

from . import views

app_name = 'blog'
urlpatterns = [
    path('', views.index, name='index'),
    path('posts/<int:pk>/', views.detail, name='detail'),
]

ここでは'posts/<int:pk>/'正確に我々は上記で定義されたURLのルールに一致します。このルールの意味は、整数に続くポスト/初めにあり、このようなポスト/ 1 /ポスト/ 255エンディング/シンボル、 / などはほかに存在し、ルールに沿ったもので<int:pk>、Djangoのルートの一致を書かれた特殊なルールがありますその役割は、対応するビューの関数のパラメータとして、デジタル・キャプチャ・キーへのユーザのアクセスをマッチングURLからですdetailユーザーが投稿/ /時間255にアクセスしたときにたとえば、(ノートDjangoのドメイン名は気にしませんが、唯一の取り出し、ドメイン名の後に相対URLを気)、<int:pk>255に一致したビュー機能の詳細に呼び出すときに、その後、255が渡され、そのパラメータ名はコロンです実際には、このようなビュー関数を呼び出し、PKの後ろに名前を指定しますdetail(request, pk=255)唯一の方法は私達が記事にアクセスしたユーザーを正確に知ることができるので、ここでは、URLからの物品のIDを取得する必要があります。

先端:

整数型int、とstrの文字タイプ、UUIDなどは、公式文書によって知ることができる場合を除いて、多くの種類がありますが、ルールに一致するジャンゴルート:パスのコンバータ

また私たちは、app_name='blog'このモジュールのurls.pyジャンゴを伝えるブログアプリケーションの一部であり、この技術は、ビュー関数の名前空間と呼ばれています。我々は2つのビューの機能がありますが、ブログの\ urls.pyを見て、エイリアス名で撮影したこれらのビューの機能は、つまり、インデックス、詳細な属性。しかし、複雑なプロジェクトでは、例えば、いくつかのサードパーティ製アプリケーションも競合にそれを防ぐために、それらを区別するためにどのようにして、インデックス、詳細ビュー機能これらのDjangoのビュー関数より呼ばれたかもしれないことがありますか?この方法は、名前空間の特定の使用は、以下に説明する方法を、APP_NAMEで名前空間を指定することです。あなたがブログの\ urls.pyにこの文を追加するのを忘れた場合は、その後、あなたはNoMatchReversed例外を取得する可能性があります。

簡単に上述したURLを生成するために、我々は、Postクラス定義get_absolute_url、方法を注意Post自体にPythonクラス、クラスであり、我々は、任意の方法を定義することができます。

blog/models.py

from django.contrib.auth.models import User
from django.db import models
from django.urls import reverse
from django.utils import timezone

class Post(models.Model):
    ...

    def __str__(self):
        return self.title
    
    # 自定义 get_absolute_url 方法
    # 记得从 django.urls 中导入 reverse 函数
    def get_absolute_url(self):
        return reverse('blog:detail', kwargs={'pk': self.pk})

URLの設定があること注意path('posts/<int:pk>/', views.detail, name='detail')、我々が設定されname='detail'、ここで便利になりました。この参照reverse機能を、その最初の引数の値は'blog:detail'意味がブログアプリケーションで、name=detail我々は上記であるように、関数app_name = 'blog'このURLモジュール語ったジャンゴは、ブログアプリケーションの一部なので、成功した次のブログアプリケーションを見つけることができジャンゴ名前は、関数の詳細図で、その後、reverse関数がURLに対応するビューを解析するように機能する、ここでのルールは、対応するディテールということであるposts/<int:pk>/int型の部分が引数の後に渡されるpk代替、もしそうであればPostID(またはPK、PK、どこのid同等)、その後、255であるget_absolute_urlポストは独自のURLを生成しますので、関数が戻るには、/ポスト/ 255 /です。

詳細ビュー機能を書きます

そして、私たちの実現があるdetail機能の眺めは:

blog/views.py

from django.shortcuts import render, get_object_or_404
from .models import Post

def index(request):
    # ...

def detail(request, pk):
    post = get_object_or_404(Post, pk=pk)
    return render(request, 'blog/detail.html', context={'post': post})

ビュー機能は、それが(すなわちPK、PKとidは同等である)記事データベースの値にレコードIDを取得し、当社の文書番号のURLからキャプチャによるとされ、非常に簡単で、その後、テンプレートに渡さ。我々はdjango.shortcutsモジュールからインポートするために使用することに注意してくださいget_object_or_404方法データベース内の投稿に対応する着信PKが存在する場合、その役割は、それが対応するが返されpost、そうでない場合、ユーザは404エラーを返し与え、そのユーザ要求を示します記事は存在しません。

書かれた詳細ページのテンプレート

次のステップは、ブログテンプレートからダウンロードしたテンプレートファイルを、記述することです(あなたがダウンロードしていない場合は、してくださいここをクリックしてダウンロードする)single.htmlテンプレートにコピーされます\(同じレベルのディレクトリにとのindex.html)ブログの下のディレクトリ、その後に社名を変更detail.html。この時点で、あなたのディレクトリ構造は次のようになります。

blogproject\
    manage.py
    blogproject\
        __init__.py
        settings.py
        ...
    blog/
        __init__.py
        models.py
        ,,,
    templates\
        blog\
            index.html
            detail.html

インデックスページブログ記事一覧でタイトルボタンの続きを読む記事はそのリンクをジャンプするハイパーリンクの上に書かれたpostユーザーは、詳細ページにジャンプしますことができるように、URLの詳細ページに対応します:

templates/blog/index.html

<article class="post post-{{ post.pk }}">
  <header class="entry-header">
    <h1 class="entry-title">
      <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
    </h1>
    ...
  </header>
  <div class="entry-content clearfix">
    ...
    <div class="read-more cl-effect-14">
      <a href="{{ post.get_absolute_url }}" class="more-link">继续阅读 <span class="meta-nav">→</span></a>
    </div>
  </div>
</article>
{% empty %}
  <div class="no-post">暂时还没有发布的文章!</div>
{% endfor %}

ここでは、二つの場所を変更し、最初は、記事のタイトルです。

<h1 class="entry-title">
  <a href="{{ post.get_absolute_url }}">{{ post.title }}</a>
</h1>

我々は、変更されたタグの属性値をてhref {{post.get_absolute_url}}。返します(私たちはPostクラスに定義)はget_absolute_urlこの方法により、テンプレート変数の使用を確認しpost、対応するURLがそうここ{{post.get_absolute_url}}が、最終的に置き換えられますpost自身のURL。

同様に、変更は、第2の読み出しボタンのリンクで継続することです:

<a href="{{ post.get_absolute_url }}" class="more-link">继续阅读 <span class="meta-nav">→</span>
</a>

だから我々は、記事のタイトルやホームボタンをクリックするとことは、詳細ページに対応した記事を読み続けるためにジャンプします。あなたは詳細ページにジャンプしようとした場合しかし、あなたはスタイルが混乱であることがわかります。これは、「ストリーキング」から「肌」のブログに私たちは、テンプレートの直接のコピーであるため、について話しましたが、また、正しく静的ファイルを処理しませんでした。私たちは、導入された方法に従って、静的ファイルを導入するためのパスを変更することができますが、すぐにあなたが任意のページで静的ファイルをインポートする必要があるすべては、各ページは変更が非常に面倒になる必要がある場合でしょう、そしてコードが繰り返されます。ここではちょうど私達は、これらの繰り返し操作を排除するのに役立つテンプレート継承方法をジャンゴています。

テンプレートの継承

私たちは、他の場所が同じで、私たちが抽出され、base.htmlに入れるの同じ部分を置くことができ、パッケージのメインラベルのさまざまな部分に加えて、index.htmlファイルとdetail.htmlファイルを参照してください。まずテンプレートディレクトリbase.htmlに新しいファイルを作成し、この時間は、あなたのプロジェクトディレクトリは次のようになるはずです。

blogproject\
    manage.py
    blogproject\
        __init__.py
        settings.py
        ...
    blog\
        __init__.py
        models.py
        ,,,
    templates\
        base.html
        blog\
            index.html
            detail.html

index.htmlファイルをbase.htmlして、パッケージのメインラベルの内容を削除するために、すべての内容をコピーし、以下の内容を置き換えます。

templates/base.html

...
<main class="col-md-8">
    {% block main %}
    {% endblock main %}
</main>
<aside class="col-md-4">
  {% block toc %}
  {% endblock toc %}
  ...
</aside>
...

ここではテンプレートブロックタグで、その役割が占有しています。{%ブロックメイン%} {%の末端ブロックメイン%が}プレースホルダブロックであり、例えば、メイン我々は、ブロックの名前をフェッチ与えます。ここでは、ブロックのラベルの役割を参照してください。detail.htmlは別にラベルの下のディレクトリ・バーよりなるため、我々はまた、脇タグ{%ブロック目次%} {%の末端ブロック目次%}プレースホルダボックスの下に追加します。場合{%ブロックTOC%が} {場合%の末端ブロック目次%}何も、{%ブロック目次%} {%TOC%の末端ブロックは}テンプレートに表示されません。しかし、の内容は、テンプレートは、ブロックの内容を表示するということです。

index.htmlのでは、我々は、ファイル内の一番上の利用{% extends 'base.html' %}継承base.htmlので、{%ブロックメイン%} {%の中で他の上に連続してbase.htmlコードを入れて 、エンドブロックメイン%} のインデックスを埋めるための場所に包まれてページの内容が表示される必要があります。

templates/blog/index.html

{% extends 'base.html' %}

{% block main %}
    {% for post in post_list %}
        <article class="post post-1">
          ...
        </article>
    {% empty %}
        <div class="no-post">暂时还没有发布的文章!</div>
    {% endfor %}
    <!-- 简单分页效果
    <div class="pagination-simple">
        <a href="#">上一页</a>
        <span class="current">第 6 页 / 共 11 页</span>
        <a href="#">下一页</a>
    </div>
    -->
    <div class="pagination">
      ...
    </div>
{% endblock main %}

{%ブロックメイン%} {%の末端ブロックメイン%}コード内のindex.htmlと同一の先頭のコードとコードにおけるようbase.html。このテンプレートは、コンテンツの{%ブロックメイン%} {%の末端ブロックメイン%}プレースホルダタグを置き換えることによってbase.html年コード、およびページの様々な他の部分の公開部分の役割を継承しています。

このテンプレートの継承にはまだ少し混乱している場合は、このアナロジーは、Pythonでの継承とクラスを継承することができます。base.htmlはindex.htmlには、サブクラスで、親クラスです。index.htmlには、base.htmlのすべてを継承しつつ、「上書き」{%ブロックメイン%} {%の末端ブロックメイン%}(を通じてブロックは親クラスとして見られる独自のコンテンツの一部コンテンツを追加するプロパティ)。

ページは、単純に、詳細に同一の継承base.html、{%ブロックメイン%} {%の末端ブロックメイン%を}対処表示するdetail.htmlコンテンツページを充填し、{%ブロック目次%} {%の末端ブロックTOC %は} base.htmlないでディレクトリの内容の一部を埋めます。現在のディレクトリがデータのみをプレースホルダしかし、我々は自動的に記事のディレクトリから抽出する方法を将来的に実現します。

templates/blog/detail.html

{% extends 'base.html' %}

{% block main %}
    <article class="post post-1">
      ...
    </article>
    <section class="comment-area">
      ...
    </section>
{% endblock main %}
{% block toc %}
    <div class="widget widget-content">
        <h3 class="widget-title">文章目录</h3>
        <ul>
            <li>
                <a href="#">教程特点</a>
            </li>
            <li>
                <a href="#">谁适合这个教程</a>
            </li>
            <li>
                <a href="#">在线预览</a>
            </li>
            <li>
                <a href="#">资源列表</a>
            </li>
            <li>
                <a href="#">获取帮助</a>
            </li>
        </ul>
    </div>
{% endblock toc %}

記事の実際のデータを聞かせて、記事のタグの下にいくつかのコンテンツを変更します。

<article class="post post-{{ post.pk }}">
  <header class="entry-header">
    <h1 class="entry-title">{{ post.title }}</h1>
    <div class="entry-meta">
      <span class="post-category"><a href="#">{{ post.category.name }}</a></span>
      <span class="post-date"><a href="#"><time class="entry-date"
                                                datetime="{{ post.created_time }}">{{ post.created_time }}</time></a></span>
      <span class="post-author"><a href="#">{{ post.author }}</a></span>
      <span class="comments-link"><a href="#">4 评论</a></span>
      <span class="views-count"><a href="#">588 阅读</a></span>
    </div>
  </header>
  <div class="entry-content clearfix">
    {{ post.body }}
  </div>
</article>

フロントページから記事のタイトルをもう一度クリックするか、詳細ページにジャンプし、ボタンを読み続け、あなたは所望の効果を見ることができます!


世間の注目HelloGitHub番号、情報およびコンテンツよりオープンソース・プロジェクトへのアクセスへようこそ

おすすめ

転載: www.cnblogs.com/xueweihan/p/11353675.html