重点是'文章ID'作为参数,如何在各个环节传递。
1、视图函数向article_list.html传递articles变量,该变量包含所有文章。
python
@login_required
def article_list(request):
articles = ArticlePost.objects.filter(author=request.user)
context = {'articles': articles, }
return render(request, 'article/column/article_list.html', context)
2、article_list.html文件中遍历articles,获得某个article的ID,并使用以下语句为'编辑图标'设置超链接。注意这个url中包含参数。
html
href="{% url 'article:redit_article' article.id %}">
html
{% for article in articles %}
<tr id={{ article.id }}>
<td>{{ forloop.counter }}</td>
<td><a href="{{ article.get_absolute_url }}">{{ article.title }}</a></td>
<td>{{ article.column }}</td>
<td>
<a name="edit" href="{% url 'article:redit_article' article.id %}">
<span class="fas fa-pencil-alt"></span>
</a>
<a name="delete" href="javascript:" onclick="del_article(this, {{ article.id }})">
<span class="fas fa-trash-alt" style="margin-left: 20px;"></span>
</a>
</td>
</tr>
{% endfor %}
3、包含参数的url的写法如下。注意这里的article_id必须就是视图函数redit_article中使用的形参,如果不一致,会报错。
python
path('redit-article/<int:article_id>/',
views.redit_article, name='redit_article'),
4、视图函数redit_article的实现如下:
如果是Get请求,就使用获得的ID得到article的信息,传递到redit_article.html页面中,渲染该页面。
如果是POST请求,就使用获得的ID,跟新数据库中的对应条目。
python
@login_required
@csrf_exempt
def redit_article(request, article_id):
if request.method == 'POST':
try:
data = json.loads(request.body)
article_title = data.get('article_title')
article_column_id = data.get('article_column_id')
article_body = data.get('article_body')
# 获取对应的栏目对象
try:
article_column = ArticleColumn.objects.get(id=article_column_id)
except ArticleColumn.DoesNotExist:
return HttpResponse("Invalid column ID", status=400)
# 更新文章
change_article = ArticlePost.objects.get(id=article_id)
change_article.title = article_title
change_article.column = article_column
change_article.body = article_body
change_article.save()
return JsonResponse({'status': 'success'})
except Exception as e:
return JsonResponse({'status': 'error', 'message': str(e)}, status=500)
elif request.method == 'GET':
article_columns = request.user.article_column.all()
article = ArticlePost.objects.get(id=article_id)
this_article_form = ArticlePostForm(initial={'title':article.title, 'body':article.body})
this_article_column = article.column
context = {'article_id':article_id,
'article_columns':article_columns,
'this_article_form':this_article_form,
'this_article_column':this_article_column}
return render(request, 'article/column/redit_article.html',
context)
5、redit_article.html文件实现如下:
html
{% extends "article/base.html" %}
{% load static %}
{% block title %}article post{% endblock %}
{% block content %}
<div style="margin-left:10px">
<form class="form-horizontal" action="." method="post">
{% csrf_token %}
<div class="row" style="margin-top: 10px;">
<div class="col-md-2 text-right"><span>标题:</span></div>
<div class="col-md-10 text-left">
<input type="text" id="id_title" name="title" value="{{ this_article_form.title.value }}">
</div>
</div>
<div class="row" style="margin-top: 10px;">
<div class="col-md-2 text-right"><span>栏目:</span></div>
<div class="col-md-10 text-left">
<select id="which_column">
{% for column in article_columns %}
{% if column == this_article_column %}
<option value="{{ column.id }}" selected="selected">
{{ column.column }}
</option>
{% else %}
<option value="{{ column.id }}">
{{ column.column }}
</option>
{% endif %}
{% endfor %}
</select>
</div>
</div>
<div class="row" style="margin-top: 10px;">
<div class="col-md-2 text-right"><span>内容:</span></div>
<div class="col-md-10 text-left">
<textarea id="id_body" name="body">{{ this_article_form.body.value }}</textarea>
</div>
</div>
<div class="row">
<input type="button" class="btn btn-primary btn-lg" value="更新">
</div>
</form>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("input[type=button]").click(function() {
redit_article();
});
});
function redit_article() {
var title = $("#id_title").val();
var column_id = $("#which_column").val();
var body = $("#id_body").val();
var id = {{ article_id }}
// 发送 AJAX 请求更新数据库,在fetch后支出了提交的url,由该url确定由那个view函数处理提交
fetch(`/article/redit-article/${id}/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': getCookie('csrftoken') // Django 的 CSRF token
},
body: JSON.stringify({
article_title: title,
article_column_id: column_id,
article_body:body,
}) //发送到后台的是一个字典
}).then(response => {
if (response.ok) {
// 提交成功
alert('文章更新成功');
// 跳转到 article_list 页面
window.location.href = "{% url 'article:article_list' %}";
} else {
// 提交失败,处理错误
alert('更新失败,请重试');
}
}).catch(error => {
console.error('Error:', error);
alert('更新失败,请重试');
});
}
// 获取 CSRF token 的函数(Django)
function getCookie(name) {
let cookieValue = null;
if (document.cookie && document.cookie !== '') {
const cookies = document.cookie.split(';');
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) === (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
}
</script>
{% endblock %}
在提交时,JavaScript函数中,使用var id = {{ article_id }}语句得到文章ID。AJAX提交时,url的写法如下'/article/redit-article/${id}/'
javascript
fetch(`/article/redit-article/${id}/`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRFToken': getCookie('csrftoken') // Django 的 CSRF token
},
body: JSON.stringify({
article_title: title,
article_column_id: column_id,
article_body:body,
}) //发送到后台的是一个字典
})