关于urlpattern中的Django pk

时间:2018-01-02 03:25:08

标签: python django url

我是Django的新手,我正在阅读github上的一个应用程序:

https://github.com/rogargon/myrecommendations/blob/web2-html/myrestaurants/urls.py#L18

有一个像

这样的urlpattern
url(r'^restaurants/(?P<pk>\d+)/$',
        RestaurantDetail.as_view(),
        name='restaurant_detail')

撤销RestaurantDetail视图,此处:https://github.com/rogargon/myrecommendations/blob/master/myrestaurants/views.py#L36

class RestaurantDetail(DetailView):
    model = Restaurant
    template_name = 'myrestaurants/restaurant_detail.html'

    def get_context_data(self, **kwargs):
        context = super(RestaurantDetail, self).get_context_data(**kwargs)
        context['RATING_CHOICES'] = RestaurantReview.RATING_CHOICES
        return context

我知道pk设置为一个表示餐馆ID的数字,但在html模型https://github.com/rogargon/myrecommendations/blob/master/myrestaurants/templates/myrestaurants/restaurant_detail.html中,我没有看到任何使用pk的地方,但页面只显示了一家餐馆。你可以pk在这个过程中如何运作?模板如何知道我想要展示哪家餐馆?为什么在这种观点中没有回报?

 {% extends "myrestaurants/base.html" %}
{% block title %}MyRestaurants - {{ restaurant.name }}{% endblock %}
{% block content %}

<span vocab="http://schema.org/" typeof="Restaurant">

<h1>
    <span property="name">{{ restaurant.name }}</span>
    {% if user == restaurant.user %}
        (<a href="{% url 'myrestaurants:restaurant_edit' restaurant.id %}">edit</a>)
    {% endif %}
</h1>

<h2>Address:</h2>
<p>
    {{ restaurant.street }}, {{ restaurant.number }} <br/>
    {{ restaurant.zipcode }} {{ restaurant.city }} <br/>
    {{ restaurant.stateOrProvince }} ({{ restaurant.country }})
</p>

<h2>
    Dishes
    {% if user.is_authenticated %}
        (<a href="{% url 'myrestaurants:dish_create' restaurant.id %}">add</a>)
    {% endif %}
</h2>
<ul>
    {% for dish in restaurant.dishes.all %}
        <li><a href="{% url 'myrestaurants:dish_detail' restaurant.id dish.id %}">
            {{ dish.name }}</a></li>
    {% empty %}<li>Sorry, no dishes for this restaurant yet.</li>
    {% endfor %}
</ul>

<h2>Reviews</h2>
{% if restaurant.restaurantreview_set.all|length > 0 %}
<span rel="aggregateRating">
    <p typeof="AggregateRating">
        Average rating <span property="ratingValue">{{ restaurant.averageRating|stringformat:".1f" }}</span>
        {% with restaurant.restaurantreview_set.all|length as reviewCount %}
        from <span property="reviewCount">{{ reviewCount }}</span> review{{ reviewCount|pluralize }}
        {% endwith %}
    </p>
</span>
<ul rel="review">
    {% for review in restaurant.restaurantreview_set.all %}
        <li typeof="Review">
            <p rel="reviewRating" typeof="Rating">
                <span property="worstRating" content="{{ RATING_CHOICES.0.0 }}"></span>
                <span property="ratingValue">{{ review.rating }}</span> star{{ review.rating|pluralize }}
                {% with RATING_CHOICES|last as best %}
                <span property="bestRating" content="{{ best.0 }}"></span>
                {% endwith %}
            </p>
            <p property="description">{% if review.comment %}{{ review.comment }}{% endif %}</p>
            <p>Created by <span property="author">{{ review.user }}</span> on
                <span property="datePublished" content="{{ review.date|date:'Y-m-d' }}">{{ review.date }}</span></p>
        </li>
    {% endfor %}
</ul>
{% endif %}

</span>

<h3>Add Review</h3>
<form action="{% url 'myrestaurants:review_create' restaurant.id %}" method="post">
    {% csrf_token %}
    Message: <textarea name="comment" id="comment" rows="4"></textarea>
    <p>Rating:</p>
    <p>{% for rate in RATING_CHOICES %}
    <input type="radio" name="rating" id="rating{{ forloop.counter }}" value="{{ rate.0 }}" />
    <label for="choice{{ forloop.counter }}">{{ rate.1 }} star{{ rate.0|pluralize }}</label>
    <br/>{% endfor %}
    </p>
    <input type="submit" value="Review" />
</form>

{% endblock %}
{% block footer %}
    Created by {{ restaurant.user }} on {{ restaurant.date }}
{% endblock %}

1 个答案:

答案 0 :(得分:0)

您所询问的行为(“模板如何知道我想要展示哪家餐馆”)是观看行为,而不是模板行为。

模板渲染器通过视图传递restaurant值。该视图没有(显式)return,因为它是class-based view - 特别是DetailView的子类。 DetailView本身继承了此视图不会覆盖的标准方法,以接受PK参数并加载特定实例。

您可以阅读DetailView的源代码,以便了解正在发生的事情,如果您愿意,例如https://github.com/django/django/blob/master/django/views/generic/detail.py - 但基于类的视图有点高级主题,并非每个项目都会使用它们。我首先关注其他领域。