如何在Django中不进入编辑器直接修改数据库字段值
问题描述
我定义了如下Django模型:
from django.db import models class Pos(models.Model): POS_TAGS = [ ('NOUN', 'NOUN'), ('ADJ', 'ADJ'), ('NUM', 'NUM'), ('PRON', 'PRON'), ('ADV', 'ADV'), ('VERB', 'VERB'), ('CNJ', 'CNJ'), ('ADP', 'ADP'), ('PRT', 'PRT'), ('INTJ', 'INTJ'), ('MOD', 'MOD'), ('IMIT', 'IMIT'), ('AUX', 'AUX'), ('PPN', 'PPN'), ('PUNC', 'PUNC'), ('SYM', 'SYM') ] token = models.CharField(max_length=150) pos = models.CharField(max_length=150, choices=POS_TAGS, null=True, default='NOUN')
Pos模型中已有部分数据。我希望无需进入Django后台管理页面,直接在主页面修改数据:通过下拉选择框选择pos字段值,点击提交即可保存到数据库。现有views.py代码如下:
from django.shortcuts import render from .models import Pos def index(request): pos = Pos.objects.all() return render(request, 'main/index.html', {'pos': pos})
当前模板已完成部分结构,需要完善为:显示token字段内容,添加对应POS_TAGS选项的下拉选择框,实现提交保存功能,模板现有代码如下:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Main</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> </head> <body> <div> {% for el in pos %} <ul class="list-group list-group-numbered"> <li class="list-group-item d-flex justify-content-between align-items-start"> <div class="ms-2 me-auto"> <div class="fw-bold">{{ el.token }}</div> </div> <div class="btn-group"> <button type="button" class="btn btn-danger">Action</button> <button type="button" class="btn btn-danger dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false"> <span class="visually-hidden">Toggle Dropdown</span> </button> <ul class="dropdown-menu"> <li><a class="dropdown-item" href="#">Action</a></li> <li><a class="dropdown-item" href="#">Another action</a></li> <li><a class="dropdown-item" href="#">Something else here</a></li> <li> <hr class="dropdown-divider"> </li> <li><a class="dropdown-item" href="#">Separated link</a></li> </ul> </div> <button type="button" class="btn btn-outline-success">Submit</button> </li> </ul> {% endfor %} </div> </body> </html>
解决方案
1. 更新视图函数(views.py)
修改视图以处理POST请求,接收修改后的POS值并更新数据库:
from django.shortcuts import render, redirect from .models import Pos def index(request): pos_entries = Pos.objects.all() if request.method == 'POST': entry_id = request.POST.get('entry_id') new_pos = request.POST.get('new_pos') if entry_id and new_pos: try: entry = Pos.objects.get(id=entry_id) entry.pos = new_pos entry.save() except Pos.DoesNotExist: pass return redirect('index') return render(request, 'main/index.html', {'pos': pos_entries})
2. 完善模板文件(index.html)
替换原有下拉按钮为表单下拉选择框,每个条目对应独立表单,实现单条数据提交:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>词性标注修改</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> </head> <body> <div class="container mt-4"> {% for el in pos %} <ul class="list-group list-group-numbered mb-2"> <li class="list-group-item d-flex justify-content-between align-items-center"> <div class="ms-2 me-auto"> <div class="fw-bold">{{ el.token }}</div> </div> <form method="POST" class="d-flex align-items-center gap-2"> {% csrf_token %} <input type="hidden" name="entry_id" value="{{ el.id }}"> <select name="new_pos" class="form-select form-select-sm"> {% for tag_value, tag_label in el.POS_TAGS %} <option value="{{ tag_value }}" {% if el.pos == tag_value %}selected{% endif %}> {{ tag_label }} </option> {% endfor %} </select> <button type="submit" class="btn btn-outline-success btn-sm">保存</button> </form> </li> </ul> {% endfor %} </div> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> </body> </html>
3. 配置URL路由(urls.py)
确保主页路由指向index视图:
from django.urls import path from . import views urlpatterns = [ path('', views.index, name='index'), ]
关键说明
- 每个条目对应独立表单,包含隐藏的条目ID和POS选择框,提交时将ID与新POS值发送到视图
- 视图处理POST请求时,根据ID找到对应条目并更新pos字段
- 使用
{% csrf_token %}防止跨站请求伪造,这是Django表单的必要安全措施 - 下拉框默认选中当前条目的pos值,提升操作体验
内容的提问来源于stack exchange,提问作者Ryadovoy Zadrot
相关产品推荐
相关产品推荐

