我有一个用户创建帖子并可以查看它们的应用程序。我面临的问题是编辑按钮以及如何只创建帖子的用户能够编辑自己的帖子或删除其他用户不能。如果我进入浏览器网址字段,例如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})
答案 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。