首页 > 解决方案 > 将可编辑表中的数据保存到数据库

问题描述

我有一个网络应用程序,后端使用 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)

当使用前端可编辑表中的任何版本时,用户更改的数据应自动更新数据库。我怎么能做到这一点?

标签: javascripthtmldjango

解决方案


使用 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


推荐阅读