我有一个应用程序,用户可以在其中创建帖子并可以查看它们。 我面临的问题是编辑按钮以及如何让只有创建帖子的用户才能编辑自己的帖子或删除它们,否则其他用户不能。 例如,如果我输入浏览器 url 字段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})
您的帖子模型与用户模型没有关系,因此要在表单或视图中包含与您的帖子模型相关的用户实例,您需要添加如下关系:
# 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 模式的情况下解析您的 url,因此在您的模板中您需要像这样在 url 中传递 post_context.slug,post_context更改为您在该视图中使用的任何上下文。
<a class="btn btn-default" href="{% url 'posts:edit' post_context.slug %}"></a>
已编辑:将 pk 更改为 slug。