在 Django 中编辑一个 slug 帖子



我有一个应用程序,用户可以在其中创建帖子并可以查看它们。 我面临的问题是编辑按钮以及如何让只有创建帖子的用户才能编辑自己的帖子或删除它们,否则其他用户不能。 例如,如果我输入浏览器 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。

相关内容

最新更新