仅在所有者的帖子上显示编辑按钮 - Django

Posted

技术标签:

【中文标题】仅在所有者的帖子上显示编辑按钮 - Django【英文标题】:Only Show Edit Button On Owner's Posts - Django 【发布时间】:2021-11-02 15:24:55 【问题描述】:

我有一个 Django 项目,其中包含帖子和编辑帖子的能力。 在主索引页面上,我显示所有帖子,例如新闻提要。 目前任何人都可以编辑任何帖子,但我想让它只有帖子的所有者才能编辑。我只是不确定如何编写 urls.py 文件,因为我正在使用:

path("", views.index, name="index"),

我可能需要将帖子 ID 或用户名传递给它,但我不确定如何编写它。我试过了:

path("index", views.index, name="index"), 
path("index/<str:pk>", views.index, name="index"),
path("index/<str:username>", views.index, name="index"),

但我得到了错误。

views.py

def index(request):
    list_of_posts = Post.objects.all().order_by('id').reverse()
    paginator = Paginator(list_of_posts, 10)
    num = request.GET.get('page', 1)
    get_page_num = paginator.get_page(num)

    return render(request, "network/index.html", 
        "list_of_posts": list_of_posts,
        "get_page_num": get_page_num,
    )

models.py

class User(AbstractUser):
    pass

class Post(models.Model):
    text = models.TextField(max_length=500, blank=True, 
null=True)
    username = models.ForeignKey('User', 
on_delete=models.CASCADE, related_name='author', 
    null=True, blank=True)
    timestamp = models.DateTimeField(auto_now_add=True)      
    like = models.ManyToManyField(
        User,  blank=True, related_name="liked_user")

    def __str__(self):
        return self.username.username 

html 显示编辑按钮。我试过了:

% if post.username == request.user.username %
              <button class="btn-btn primary" my-id="i.id" id="ebutton- 
i.id" onclick="edit_form(this)" >Edit</button>
              <br><br><br> 
% endif %

此页面的完整html:

% extends "network/layout.html" %
% load static %
% block body %
<br>
 <h3> <center> Welcome. Here is your news feed: </center> </h3>
 <br>

% for i in get_page_num %

<div class='card mb-3' style="max-width: 530px;" id="card-posts">

  <div class="row no-gutters">
   <div class="col-md-8">
    <div class="card-body">
     <h5 class="card-title"><a href="% url 'profile' 
     username=i.username %">i.username</a></h5>
          
    <span id="textinfo-i.id" 
    class="post">i.text</span> <br> 
    <textarea my-id="i.id" id="edit-me-i.id" 
    style="display:none;" class="form-control 
    textarea" row="3">i.text</textarea>
          
     <br>
     <p class="card-text">i.timestamp</p>

      <div class="like mt-1">
      <img my-id="i.id" id="is-it-liked-i.id" 
      class="like-class"
  
      % if not request.user in i.like.all %
  
       clicked="no" 
       src="https://img.icons8.com/emoji/452/white-heart.png"
  
         %else%
  
         clicked="yes" 
        src="https://img.icons8.com/emoji/452/red-heart.png"
  
         %endif%
          /> <span id="post-count-i.id">i.like.count. 
          </span>
          </div>

           <br>
          % if request.user == post.username %
          <button class="btn-btn primary" my-id="i.id" 
     id="ebutton-i.id" onclick="edit_form(this)" 
  >Edit</button>
    <br><br><br> 
          % endif %

              </div>
            </div>
          </div>
        </div>

% endfor %
<br><br>

<div class="pagination">
<span class="step-links">
  % if get_page_num.has_previous %  
      <a href="?page= get_page_num.previous_page_number " 
class="page-link">Previous</a>
  % else %
  
  <li class="page-item disabled"><a class="page- 
link">Previous</a></li>
  % endif %

 % if get_page_num.has_next %
 <a href="?page= get_page_num.next_page_number " class="page- 
link">Next</a>
 % else %

  <a class="page-link">Next</a>
 % endif %
</span>
</div>
% endblock %


 % block script % <script src="% static 
 'network/network.js'%"></script> % endblock %

通过这种方式,我需要将用户名传递给 url,但我不能,不会出错。 总的来说,我只是在寻求建议,关于如何使编辑按钮只出现在当前用户是所有者的帖子上。这样一来,任何人都无法编辑其他任何人的帖子。

【问题讨论】:

【参考方案1】:

如果您想显示所有帖子并且只允许帖子作者编辑它,您需要在模板上下文中注入所有帖子和请求用户。然后在您的模板中遍历帖子并检查作者是否等于请求用户,然后再显示编辑按钮。但首先你需要在你的文章模型中使用一个外键来引用作者。

Urls.py

urlpatterns = [path("index/", views.index, name="index")]

观看次数

def index(request):
    list_of_posts = Post.objects.order_by('-id')
    request_user = request.user

    return render(request, "network/index.html", 
        "list_of_posts": list_of_posts,
        "request_user": request_user
    )

模型

class Post(models.Model):
    user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='posts')
    # Other fields

模板

% if post.user == request_user %
    <!--Show the edit button-->
% endif %

您也可以直接访问模板中的请求对象:

% if post.user == request.user %
    <!--Show the edit button-->
% endif %

【讨论】:

@RedWheelbarrow 我尝试了你所说的 url - 但我得到 django 404 错误未找到。为了访问模板中的请求对象,我也这样做了。我的模型称为 Post,我将“用户名”作为属性,所以我做了 % if post.username == request.user % 但编辑按钮仍然没有显示在该页面上的所有帖子上。 @user14567126 如果Post.username 字段包含作者的用户名,则使用此条件:% if post.username == request.user.username %。或者,如果您更喜欢在序列化程序的上下文中注入请求用户:% if post.username == request_user.username %。如果Post.username 不包含字符串,请提供您的PostUser 模型的详细信息。 @RedWheelbarrow 我用我的模型和我尝试过的简化视图更新了这个页面。在 html 中,我尝试了您的建议以及其他建议,例如:如果 post.username == request.user.username,如果 post.username == request.username.username 等。我现在没有收到任何错误,但是编辑按钮要么出现在所有帖子上,要么不出现在任何帖子上。我只需要它出现在 request.user 是作者的帖子上。 @user14567126 试试这个:% if request.user == post.username %。如果这不起作用,请同时提供您的模板代码(尤其是您迭代帖子的部分)。 @RedWheelbarrow 我更新了页面以获得完整的 html 文件。我正在使用分页,其中部分代码用于遍历帖子。我最初认为这不会有什么不同,所以我没有包括它。但你可能是对的,很抱歉造成混乱。我的观点也更新了。【参考方案2】:
% if request.user == post.author %
    <button>Delete</button>
% endif %

这假设您有一个Post 模型,其属性为author

【讨论】:

【参考方案3】:

我需要添加

% if request.user == i.username %

因为我在 html 页面中循环,for i in get_page_num:。我以前没有 i。

【讨论】:

以上是关于仅在所有者的帖子上显示编辑按钮 - Django的主要内容,如果未能解决你的问题,请参考以下文章

Django ajax GET 403(禁止)

如何禁用编辑和删除rails_admin?

jQuery 仅在 DOM 中单击时查找下一个表单元素

django summernote 无法正常工作

php 显示相同分类中的相关自定义帖子 - 仅在单页上显示

PHP Wordpress - 仅在特定类别的第一页上显示精选帖子