javascript - 用 JS 和 Django 修改一篇文章?
问题描述
我目前正在研究 CS50Web 网络项目 4,我一直在编辑显示的许多帖子中的一个帖子。
我有一个显示用户完成的所有帖子的视图。
def profile(request, username):
if request.method == "GET":
user = User.objects.filter(username=username)
profile = Profile.objects.filter(user=user[0]).get()
posts = Post.objects.filter(user=user[0]).order_by('-publish_date')
return render(
request,
'network/profile.html',
{
'posts': page,
'profile': profile,
}
)
并显示在 html 模板中。
{% for post in posts %}
<div class="card text-center">
<div class="card-header">
<a href="{% url 'profile' post.user %}"> {{ post.user }} </a>
</div>
<div class="card-body">
<h5 class="card-title">{{ post.content }}</h5>
<p class="card-text">{{ post.num_likes }}</p>
<a href="#" class="btn btn-primary" onclick="editpost()"> Edit </a>
</div>
<div class="card-footer text-muted">
{{ post.publish_date }}
</div>
</div>
<br>
{% endfor %}
我知道我需要一个函数来使用 JS 从该特定表单中更改<h5>
标签和<p>
标签,但我知道如何仅从一个帖子中获取它,而不是从 Django 模板引擎生成的所有帖子中获取它。
一旦我可以选择它们,我会将它们的信息复制到一个 var 中并更改样式,这样显示就不会像创建介绍一样,我将介绍来自 var 的数据并允许用户修改它们。
然后将创建一个新的<a>
was 供用户保存更改。目前,我正在考虑使用 Ajax 将数据发送回服务器,但如果有更好的建议,我愿意接受建议。
我会上传数据库的模型,但我认为这没有必要。非常感谢任何帮助或指导。
解决方案
您在模板中使用的 JavaScript 提供了有关如何为用户 (ie for post in posts
) 访问每个帖子以及如何设置该帖子的h5
元素 (ie post.content
) 和p
元素 (ie post.num_likes
) 中出现的值的线索。
要更新视图中的所有这些,您可以执行以下操作:
posts = Post.objects.filter(user=user[0]).order_by('-publish_date');
for (let post in posts){
post.content = my_new_content;
post.num_likes = my_new_num_likes;
}
return render( // etc...
或者,如果您想保持基础值不变,只更新 DOM(模板)值,您只需将模板更新代码更改为:
<h5 class="card-title">{{ my_new_content }}</h5>
<p class="card-text">{{ my_new_num_likes }}</p>
我对这部分感到困惑:“...更改样式以使显示不存在以及创建介绍是我将介绍数据...”,但是如果您在渲染后尝试访问 DOM 元素,在 MDN 上记录了几种有用的相关技术。
对于您的情况,如果所有卡片都出现在同一页面上,您可能会执行以下操作:
const
// Defines an array to hold values found in the DOM
oldCardInfoArray = [],
// Collects references to all card elements on the page
cards = document.getElementsByClassName("card"),
// Converts cards to an array, and gets only those cards whose user matches `post.user`
// (Assumes this code has access to some `post` object with a `user` property)
userCards = (Array.from(cards)).filter(
(card) => card.querySelector("a").textContent.trim() == post.user)
);
// Loops through the userCards
for(let userCard of userCards){
const
// Identifies title and text of each card (as `oldTitle` and `oldText`, respectively)
cardTitleElement = userCard.querySelector(".card-title"),
cardTextElement = userCard.querySelector(".card-text"),
oldTitle = cardTitleElement.textContent,
oldText = cardTextElement.textContent,
// Makes an `oldCardInfo` object with two properties, and adds it to the array
oldCardInfo = { oldTitle: oldTitle, oldText: oldText };
oldCardInfoArray.push(oldCardInfo);
}
// Now the array is populated, and we can do something with its contents
for(let card of oldCardInfoArray){
const oldTitle = card.oldTitle;
const oldText = card.oldText;
// Prints the values from each card to the browser console
// (or you could send them to the server, or whatever)
console.log("title: " + oldTitle + ", text: " + oldText);
}
显然,所有这些代码都未经测试,但它至少应该给你一些想法。
编辑:
作为对您的评论的回应,要选择包含单击按钮的卡片,您可以将这样的代码放入您的editPost
函数中:
const card = this.closest(".card");
因此,现在,您将能够仅使用卡片中用户与之交互的那些元素,而不是循环遍历卡片(就像cardTitleElement
上面的 with 一样)。
或者,或者,您可以将内联事件处理程序(onclick = editPost()
在模板中)替换为事件侦听器,或者 1)在<script>
模板底部的元素内或 2)直接在现有 JavaScript 代码中(尽管我不确定哪个Django 的一部分处理了第二种方法)。它可能看起来像:
document.addEventListener("click", editPost);
function editPost(event){ // Listener sees triggering event
const clickedThing = event.target; // Event has useful properties
const userCard = clickedThing.closest(".card");
if(userCard){ // Makes sure button has a `card` ancestor before proceeding
// Now, with the correct card identified, we can collect values from it
const cardTitleElement = userCard.querySelector(".card-title");
const cardTextElement = userCard.querySelector(".card-text");
// ...etc, as described above
}
}
推荐阅读
- ruby - Carrierwave 是线程安全的吗?
- pyspark - 如何将 PySpark 数据框写入 DynamoDB 表?
- ios - 在上传到应用商店之前创建我的应用的应用商店链接
- javascript - 无法使用 Jquery 替换文本
- javascript - findOneAndUpdate - 只返回数组中推送的项目
- php - 计算用TCPDF绘制的pdf文件中曲线的长度
- xml - 通过搜索 id 使用批处理脚本删除 xml 标记的文本数据中的一大块行
- angular - 尝试区分“[object Object]”时出错。角度中只允许使用数组和可迭代对象
- javafx - JavaFX 单元格样式
- c# - 将 .Net Core 项目发布到 Web,带有域和 1 个 SQL 数据库