在django编辑slu post帖子

时间:2018-03-06 22:57:48

标签: python django

我有一个用户创建帖子并可以查看它们的应用程序。我面临的问题是编辑按钮以及如何只创建帖子的用户能够编辑自己的帖子或删除其他用户不能。如果我进入浏览器网址字段,例如http://127.0.0.1:8000/soko/edit,则会打开表单字段并准备进行编辑,但如果我使用模板中的输入按钮,则会收到以下错误Reverse for 'edit' with no arguments not found. 1 pattern(s) tried: ['(?P<slug>[\\w-]+)/edit/$']

下面是我的 views.py

def edit(request, slug = None):
    instance = get_object_or_404(Post, slug = slug)
    form = PostForm(request.POST or None, request.FILES or None, instance = instance)
    if form.is_valid():
        instance = form.save(commit=False)
        instance.save()
        messages.success(request, "Post updated")
        #redirecting to landing page
        return HttpResponseRedirect(instance.get_absolute_url())

    context = {
        "title": instance.title,
        "instance": instance,
        "form": form,
    }
    template = 'edit.html'
    return render(request, template, context)

def delete(request, slug=None):
    instance = get_object_or_404(Post, slug=slug)
    instance.delete()
    messages.success(request, "Post Deleted")
    return redirect(index)

urls.py

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

HTML

<a class="btn btn-default" href="{% url 'posts:edit' %}"></a>

forms.py

 class PostForm(forms.ModelForm):

    class Meta:
        model = Post

        fields = [
            "title",
            "content",
        ]

models.py

class Post(models.Model):
    title = models.CharField(max_length = 120)
    slug = models.SlugField(unique= True)
    content = models.TextField()

    def __str__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("posts:more", kwargs={"slug": self.slug})

1 个答案:

答案 0 :(得分:1)

您的帖子模型与用户模型没有关系,因此要在表单中包含用户实例,或者在Post模型中包含您需要添加如此关系的视图:

# models.py

# include the User model
from django.contrib.auth.models import User

class Post(models.Model):
    .....
    created_by = models.ForeignKey(User)

您的观点必须处理请求的用户及其与实例的关系以及验证和限制请求访问权限。

# views.py
# restrict the view to only the user who created the instance.

from django.core.exceptions import PermissionDenied

# A custom access decorator to check if the request.user 
# is the owner of the instance 
def  restrict_user_access(function):
    def wrap(request, *args, **kwargs):
        posts =  Post.objects.get(slug=kwargs['slug'])
        if post.created_by != request.user:
            raise PermissionDenied
        return function(request, *args, **kwargs)

    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap

@restrict_user_access
def edit(request, slug = None):
   instance = get_object_or_404(Post, slug = slug)
   form = PostForm(request.POST or None, request.FILES or None, instance =instance)
   if form.is_valid():
        ....
        # add the request.user to created_by
        form.instance.created_by = request.user
        form.save()

@restrict_user_access
def delete(request, slug=None):
    .....

发生反向错误是因为django无法解析您的网址而没有您在urls.py中描述的slug模式,所以在您的模板中,您需要在网址中传递post_context.slug,如此更改post_context到你在该视图中使用的任何上下文。

<a class="btn btn-default" href="{% url 'posts:edit' post_context.slug %}"></a>

编辑:将pk更改为slug。