Danny
Danny

Reputation: 510

Trying to allow users to edit own articles -- Django

I'm trying to make it so users can edit articles that they created. I feel like I'm close, but can't quite bridge the gap of what I've done and what I need to do.

template on the article detail page:

{% if request.user == article.author %}
    <p>
      <a href="{% url 'articles:edit_article' %}"
        Edit article
      </a>
    </p>
    {% endif %}

This seems to work okay.

urls.py:

url(r'^(?P<slug>[\w-]+)/$', views.article_detail, name="detail"),
url(r'^(?P<slug>[\w-]+)/edit/$', views.edit_article, name="edit_article"),

views.py:

def edit_article(request):
if request.method == 'POST':
    form = forms.EditArticle(request.POST, slug=request.slug)
    if form.is_valid():
        form.save()
        return redirect('articles:list')
else:
    form = forms.EditArticle(slug=request.slug)
    args = {'form': form}
    return render(request, 'articles/edit_article.html', args)

forms.py

class EditArticle(forms.ModelForm):
class Meta:
    model = models.Article
    fields = (
        'title',
        'body',
        'slug',
        'thumb'
    )

And edit_article.html:

{% extends 'base_layout.html' %}

{% block content %}
<h1>Edit Article {{ article.title }}</h1>
<div class="profile">
  <form method="post">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Update Profile</button>
  </form>
</div>
{% endblock %}

Here's the traceback:

Traceback:

File "C:\Python27\lib\site-packages\django\core\handlers\exception.py" in inner
  41.             response = get_response(request)

File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "C:\Python27\lib\site-packages\django\core\handlers\base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "C:\Users\...\...\...\articles\views.py" in article_detail
  18.     return render(request, "articles/article_detail.html", {'article':article})

File "C:\Python27\lib\site-packages\django\shortcuts.py" in render
  30.     content = loader.render_to_string(template_name, context, request, using=using)

File "C:\Python27\lib\site-packages\django\template\loader.py" in render_to_string
  68.     return template.render(context, request)

File "C:\Python27\lib\site-packages\django\template\backends\django.py" in render
  66.             return self.template.render(context)

File "C:\Python27\lib\site-packages\django\template\base.py" in render
  207.                     return self._render(context)

File "C:\Python27\lib\site-packages\django\template\base.py" in _render
  199.         return self.nodelist.render(context)

File "C:\Python27\lib\site-packages\django\template\base.py" in render
  990.                 bit = node.render_annotated(context)

File "C:\Python27\lib\site-packages\django\template\base.py" in render_annotated
  957.             return self.render(context)

File "C:\Python27\lib\site-packages\django\template\loader_tags.py" in render
  177.             return compiled_parent._render(context)

File "C:\Python27\lib\site-packages\django\template\base.py" in _render
  199.         return self.nodelist.render(context)

File "C:\Python27\lib\site-packages\django\template\base.py" in render
  990.                 bit = node.render_annotated(context)

File "C:\Python27\lib\site-packages\django\template\base.py" in render_annotated
  957.             return self.render(context)

File "C:\Python27\lib\site-packages\django\template\loader_tags.py" in render
  72.                 result = block.nodelist.render(context)

File "C:\Python27\lib\site-packages\django\template\base.py" in render
  990.                 bit = node.render_annotated(context)

File "C:\Python27\lib\site-packages\django\template\base.py" in render_annotated
  957.             return self.render(context)

File "C:\Python27\lib\site-packages\django\template\defaulttags.py" in render
  322.                 return nodelist.render(context)

File "C:\Python27\lib\site-packages\django\template\base.py" in render
  990.                 bit = node.render_annotated(context)

File "C:\Python27\lib\site-packages\django\template\base.py" in render_annotated
  957.             return self.render(context)

File "C:\Python27\lib\site-packages\django\template\defaulttags.py" in render
  458.             url = reverse(view_name, args=args, kwargs=kwargs, current_app=current_app)

File "C:\Python27\lib\site-packages\django\urls\base.py" in reverse
  91.     return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))

File "C:\Python27\lib\site-packages\django\urls\resolvers.py" in _reverse_with_prefix
  497.         raise NoReverseMatch(msg)

Exception Type: NoReverseMatch at /articles/testing-1212/
Exception Value: Reverse for 'edit_article' with no arguments not found. 1 pattern(s) tried: [u'articles/(?P<slug>[\\w-]+)/edit/$']

I'm guessing the problem is in the view with the slug. I'm trying to base this around my working view for editing the user profile, so I'm guessing there is something that I lost in translation. I feel like this is just one or two tweaks from working. Any ideas?

Upvotes: 2

Views: 550

Answers (1)

Lemayzeur
Lemayzeur

Reputation: 8525

You should have:

{% if request.user == article.author %}
 <p>
  <a href="{% url 'articles:edit_article' article.slug %}"
    Edit article
  </a>
</p>
{% endif %}

your views

def edit_article(request,slug):
    article = Article.objects.get(slug=slug) # Better to use get_object_or_404 from django.http
    if request.method == 'POST':
        form = forms.EditArticle(request.POST, instance=article)
         if form.is_valid():
              form.save()
              return redirect('articles:list')
    else:
         form = forms.EditArticle(instance=article)
    args = {'form': form}
    return render(request, 'articles/edit_article.html', args)

Upvotes: 1

Related Questions