javascript - 将可编辑表中的数据保存到数据库
问题描述
我有一个网络应用程序,后端使用 Django,前端使用 HTML5。Restful API(Django rest 框架)用于 GET、PUT、POST 和 DELETE 数据类型。
在 HTML 页面中,我有一个可编辑的表格,它应该将任何已编辑的内容保存到数据库中。
我怎样才能做到这一点?</p>
HTML5 页面:
<table id="thisTable" contenteditable='true' class="table table-bordered table-sm" width="100%" cellspacing="0" style="font-size: 1.0rem;"
id="bk-table"
data-toggle="table"
data-toolbar="#toolbar"
data-cookie="true"
data-cookie-id-table="materialId"
data-show-columns="true"
data-show-refresh="true"
data-show-fullscreen="true"
data-show-export="true"
data-height="650"
{# data-sticky-header="true"#}
{# data-sticky-header-offset-left="7em"#}
{# data-sticky-header-offset-right="7em"#}
data-click-to-select="true"
data-id-field="id"
data-show-footer="true"
data-url="/api/materials/"
data-query-params="queryParams"
data-remember-order="true"
data-pagination="true"
data-side-pagination="server"
data-total-field="count"
data-data-field="results">
<thead class="thead-dark" >
<tr contenteditable='true'>
<!--th data-sortable="true" >ID</th-->
<th data-field="courseCode" data-formatter="renderCourse">Course Code</th>
<th data-field="type">Course Type</th>
<th data-field="school">School</th>
<th data-field="discipline.name">Discipline</th>
<th data-field="discipline.hop1">HOP Name</th>
<th data-field="discipline.hop1_email">HOP Email</th>
<th data-field="discipline.executive">Executive Name</th>
<th data-field="discipline.executive_email">Executive Email</th>
</tr>
</thead>
</table>
休息.py:
class MaterialSerializer(serializers.ModelSerializer):
book = BookSerializer(many=False)
course = CourseSerializer(many=False)
# should not use SemesterCourseSerializer this because it also include books
# setting allow_null True so that this field always present in the output, otherwise it will not present when null
# that cause datatable alert error when render missing field.
school = serializers.ReadOnlyField(source='course.courseInfo.school.name', allow_null=True)
#courseCode = serializers.ReadOnlyField(source='course.courseInfo.code')
courseId = serializers.ReadOnlyField(source='course.courseInfo.id')
year = serializers.ReadOnlyField(source='course.semester.year')
month = serializers.ReadOnlyField(source='course.semester.month')
term = serializers.ReadOnlyField(source='course.semester.term')
quota = serializers.ReadOnlyField(source='course.quota')
type = serializers.ReadOnlyField(source='course.courseInfo.type')
available = serializers.ReadOnlyField(source='course.courseInfo.available')
postgraduate = serializers.ReadOnlyField(source='course.courseInfo.postgraduate')
discipline = DisciplineSerializer(source='course.courseInfo.discipline')
retail_price_display = serializers.ReadOnlyField(source='book.retail_price_display')
courseCode = serializers.SerializerMethodField()
def get_courseCode(self, obj):
return f'{obj.course.courseInfo.discipline_code}{obj.course.courseInfo.code}'
class Meta:
model = Material
fields = ['id', 'book', 'course', 'type','school', 'available', 'postgraduate', 'courseCode', 'courseId', 'year', 'month', 'term', 'quota',
'modified', 'discipline', 'remark', 'is_discard', 'discard_reason', 'retail_price_display']
class MaterialList(generics.ListAPIView):
queryset = Material.objects.all()
serializer_class = MaterialSerializer
permission_classes = [permissions.IsAuthenticated]
def get_queryset(self):
print(self.request.query_params)
sort_by_column_idx = self.request.query_params.get('order[0][column]', 0)
queryset = Material.objects.all()
sort = self.request.query_params.get("columns[{}][data]".format(sort_by_column_idx), 'id')
if sort.startswith('book'):
sort = sort.replace('.', '__')
elif sort == 'school':
sort = 'course__courseInfo__school'
elif sort == 'course.courseCode':
sort = 'course__courseInfo__code'
print('sort by', sort) # to fix order by school and other ref fields
order = self.request.query_params.get('order[0][dir]', 'asc')
if order == 'desc':
sort = '-' + sort
# filter by preparation
preparation = self.request.query_params.get('prep')
if preparation:
queryset = queryset.filter(preparation__slug=preparation)
# filter by course code
course = self.request.query_params.get('code')
if course:
queryset = queryset.filter(course__course__code=course)
# filter by school
school_filter = self.request.query_params.get('school')
if school_filter:
schools = School.objects.filter(code__in=school_filter.split(",")).all()
queryset = queryset.filter(course__course__school__in=schools)
# filter by publisher
publisher_filter = self.request.query_params.get('publisher')
if publisher_filter:
publishers = Publisher.objects.filter(name__in=publisher_filter.split(",")).all()
print(publishers)
queryset = queryset.filter(book__publisher__in=publishers)
# filter by format
format_filter = self.request.query_params.get('limit')
if format_filter:
queryset = queryset.filter(book__Format_issued=format_filter)
# filter by dis
discipline_filter = self.request.query_params.get('discipline')
print(discipline_filter)
if discipline_filter:
queryset = queryset.filter(course__courseInfo__discipline__name=discipline_filter)
Add_Information = self.request.query_params.get('Add_Information')
return queryset.order_by(sort)
当使用前端可编辑表中的任何版本时,用户更改的数据应自动更新数据库。我怎么能做到这一点?
解决方案
使用 Mutation Observer 跟踪可编辑的内容。每次发生更改时,您都应该运行一个 querySelects any 的函数data-field
。
因此,在观察变化时,您可以运行以下内容:
function callback() {
const table = document.getElementById("bk-table");
// data is mutable object, but you can't do `data =` again
const data = {};
for (const x of table.querySelectorAll("[data-field]")) {
data[x.dataset.field] = x.innerText;
}
// send the API call
fetch(url, etc.)
}
(() => {
const config = { characterData: true };
for (const nodes of document.getElementById("bk-table").querySelectorAll("[data-field]")) {
const observer = new MutationObserver(callback);
// Start observing the target node for configured mutations
observer.observe(node, config);
}
})();
突变观察者文档:https ://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
推荐阅读
- android - 获取 java.lang.VerifyError: Verifier denied class com.google.android.gms.measurement.internal.zzfl
- javascript - 为什么使用 Promise 将结果保存在变量中会产生更好的性能?
- javascript - 使用 express js 和 vuejs 提供不同的本地 json 数据
- c - 进程返回 -1073741819 (0xC0000005)(在一个简单的矩阵中)
- r - 如何将时间数据提供给 h2o?
- c++ - 在 Visual Studio Code 中使用 C++ 进行调试时如何读取输入而不丢失编码?
- nim-lang - 有什么方法可以从同一目录中的其他文件导入本地 proc?
- selenium - 在 selenium webdrievr 中按 ctrl + tab
- javascript - 我的不和谐计数机器人不是逐台服务器而是每台服务器组合
- java - 从另一个活动 android 访问和更新 textview