# articleapp\decorator.py
def article_ownership_required(func):
def decorated(request, *args, **kwargs):
article = Article.objects.get(pk=kwargs['pk'])
if not article.writer == request.user:
return HttpResponseForbidden()
return func(request, *args, **kwargs)
return decorated
# articleapp\views.py
# ...
@method_decorator(article_ownership_required, 'get')
@method_decorator(article_ownership_required, 'post')
class ArticleUpdateView(UpdateView):
model = Article
form_class = ArticleCreationForm
context_object_name = 'target_article'
template_name = 'articleapp/update.html'
def get_success_url(self):
return reverse('articleapp:detail', kwargs={'pk': self.object.pk})
<!-- articleapp\detail.html -->
{% extends 'base.html' %}
{% block content %}
<div style="text-align: center; max-width: 500px; margin: 4rem auto">
<h1>
{{ target_article.title }}
</h1>
<img src="{{ target_article.image.url }}" alt="">
<p>
{{ target_article.content }}
</p>
<a href="{% url 'articleapp:update' pk=target_article.pk %}">
<p>Update Article</p>
</a>
</div>
{% endblock %}
<!-- articleapp\update.html -->
{% extends 'base.html' %}
{% load bootstrap4 %}
{% block content %}
<div style="text-align: center; max-width: 500px; margin: 4rem auto">
<div class="mb-4">
<h4>Update Article</h4>
</div>
<form action="{% url 'articleapp:update' pk=target_article.pk %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% bootstrap_form form %}
<input type="submit" class="btn btn-dark rounded-pill col-6 mt-3">
</form>
</div>
{% endblock %}