ویوی بروزرسانی | Update View

سلام

بیایید به پیاده سازی پروژۀ خودمان باز گردیم. این بار می خواهیم از GCBV برای پیاده سازی ویوی مربوط به edit post استفاده کنیم.

boards/views.py (مشاهده کد کامل)

from django.shortcuts import redirect
from django.views.generic import UpdateView
from django.utils import timezone

class PostUpdateView(UpdateView):
    model = Post
    fields = ('message', )
    template_name = 'edit_post.html'
    pk_url_kwarg = 'post_pk'
    context_object_name = 'post'

    def form_valid(self, form):
        post = form.save(commit=False)
        post.updated_by = self.request.user
        post.updated_at = timezone.now()
        post.save()
        return redirect('topic_posts', pk=post.topic.board.pk, topic_pk=post.topic.pk)

با UpdateView  و CreateView امکان تعریف form_class یا fieldها را در اختیار داریم.

در مثال بالا از fields برای ساخت فرم مدل به صورت موقتی استفاده کرده ایم.

جنگو با این کار از یک فرم مدل برای ارسال یک فرم با استفاده از مدل پست استفاده خواهد کرد.

فرم مذکور یک فرم بسیار ساده و صرفاً دارای فیلدی به نام message است. به دلیل سادگی فیلدهای فرم، پیاده سازی درون همین کلاس انجام شده اما برای فرم هایی با فیلدهای بیشتر توصیه می شود که خارج از این کلاس، فرم مدل خود را پیاده سازی کرده و در این قسمت به آن لینک و ارجاع دهیم.

خط مربوط به template_name هم که مشخص بوده و به قالب مربوط به فرم اشاره دارد.

از متغیر pk_url_kwarg برای شناسایی نام آرگومانی استفاده خواهد شد که قرار است برای بازیابی شی Post استفاده شود. این نام مشابه نام تعریف شده در urls.py است.

اگر ویژگی context_object_name در خط بعدی را تنظیم و مقداردهی نکنیم؛ شی Post در قالب های برنامه به عنوان یک «.object» قابل دسترسی خواهد بود و برای دسترسی به فیلدهای آن باید از کلمۀ object استفاده کنیم. اینکار خوانایی برنامه را کم کرده و حتی امکان تصادم به وجود می آید. بنابراین از context_object_name استفاده می کنیم تا آن را به Post تغییر نام دهیم. نحوۀ استفاده از آن در قالب edit_post.html و به شکل زیر دیده می شود. موضوع بعد از خواندن مثال زیر واضح می شود.

در این مثال خاص لازم است متد فعلی ()form_valid را با هدف تنظیم فیلدهای بیشتری نظیر updated_by و updated_at وارد کنیم.

قابل مشاهده است که متد ()form_valid اولیه شبیه UpdateView#form_valid است.

myproject/urls.py (مشاهده کد کامل)

from django.conf.urls import url
from boards import views

urlpatterns = [
    # ...
    url(r'^boards/(?P<pk>\d+)/topics/(?P<topic_pk>\d+)/posts/(?P<post_pk>\d+)/edit/$',
        views.PostUpdateView.as_view(), name='edit_post'),
]

حالا می توانیم لینکی را برای ویرایش صفحه اضافه کنیم.

templates/topic_posts.html (مشاهده کد کامل)

{% if post.created_by == user %}
  <div class="mt-3">
    <a href="{% url 'edit_post' post.topic.board.pk post.topic.pk post.pk %}"
       class="btn btn-primary btn-sm"
       role="button">Edit</a>
  </div>
{% endif %}

templates/edit_post.html (مشاهده کد کامل)

{% extends 'base.html' %}

{% block title %}Edit post{% endblock %}

{% block breadcrumb %}
  <li class="breadcrumb-item"><a href="{% url 'home' %}">Boards</a></li>
  <li class="breadcrumb-item"><a href="{% url 'board_topics' post.topic.board.pk %}">{{ post.topic.board.name }}</a></li>
  <li class="breadcrumb-item"><a href="{% url 'topic_posts' post.topic.board.pk post.topic.pk %}">{{ post.topic.subject }}</a></li>
  <li class="breadcrumb-item active">Edit post</li>
{% endblock %}

{% block content %}
  <form method="post" class="mb-4" novalidate>
    {% csrf_token %}
    {% include 'includes/form.html' %}
    <button type="submit" class="btn btn-success">Save changes</button>
    <a href="{% url 'topic_posts' post.topic.board.pk post.topic.pk %}" class="btn btn-outline-secondary" role="button">Cancel</a>
  </form>
{% endblock %}

همانطور که گفته شد برای دسترسی به شی پست از post.topic.board.pk استفاده می کنیم. اما اگر context_object_name را با مقدار Post تغییر نداده بودیم برای دسترسی به آن باید از عبارت object.topic.board.pk استفاده می کردیم. حالا موضوع روشن شد؟!!

ترجمۀ اختصاصی توسط تمدن

 

مطلب بعدی: تست ویوی بروزرسانی

مطلب قبلی: Generic Class-Based View

0 پاسخ

دیدگاه خود را ثبت کنید

تمایل دارید در گفتگو شرکت کنید؟
نظری بدهید!

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *