如何使用多个 Django FBV 通过 Ajax+jQuery 捕获和保存数据

Posted

技术标签:

【中文标题】如何使用多个 Django FBV 通过 Ajax+jQuery 捕获和保存数据【英文标题】:How to use multiple Django FBVs in capturing and saving data through Ajax+jQuery 【发布时间】:2020-10-18 18:43:29 【问题描述】:

在我的 Django 应用程序中,我使用了两个函数视图,FV1 和 FV2。

FV1 用于从数据库中捕获数据并填充表单/表单集。

在 FV2 中,我尝试使用 Ajax 从页面发送序列化数据(带有上述数据),验证 FV2 中的数据并保存,最后在页面中接收来自 FV2 的确​​认作为 Ajax 回调。

在控制台中我可以看到序列化的数据。验证发生的事实证明,如果未键入所需值之一,则相关else: 段中捕获的错误消息将传递到控制台。

但是,如果正确输入了所有数据并提交了表单,则数据不会保存在相应的模型中。也没有错误信息。

鉴于上述情况,实现目标的方法应该是什么。不用说,我错过了一些大事。非常感谢您提供解决问题的指导。

编辑

models.py:

class mapTarg(models.Model):
    map_id = models.AutoField(primary_key=True, verbose_name='Map ID')
    map_name = models.CharField(max_length=50, verbose_name='Map name')
    map_target = models.CharField(max_length=100, verbose_name='Target')

class mapTargItems(models.Model):
    map_itm = models.AutoField(primary_key=True, verbose_name='Item')
    map_hdr = models.ForeignKey(mapTarg, related_name='map_hdr_tab', on_delete=models.CASCADE, verbose_name='Mapper')
    map_field = models.CharField(max_length=100, verbose_name='Target Fld')
    map_field_col = models.CharField(max_length=25, verbose_name='Col')

views.py:

def SaveMapAjax(request, object_id=False):
    if object_id:
        qs_targ_model_form = mapTarg.objects.get(pk=object_id)
    else:
        qs_targ_model_form = mapTarg()

    target_field_formset = CreateMappedTargFieldsFormset()

    if request.method == 'POST' and request.is_ajax():
        new_qs_targ_model_form = mappedTargModelForm(data=request.POST, instance=qs_targ_model_form)

        if new_qs_targ_model_form.is_valid():
            qs_targ_model_form = new_qs_targ_model_form.save(commit=False)
            target_field_formset = CreateMappedTargFieldsFormset(request.POST, instance=qs_targ_model_form)

            if target_field_formset.is_valid():
                qs_targ_model_form.save()
                target_field_formset.save()

            msg='Data saved!'

        else:
            msg= 'Error occured..'
    return JsonResponse(msg, safe=False)

ajax 函数

$(function() 
    $('#btnSaveMap').on('click', function()     // "Save" button
    var frm = $('#dataMapperForm');              // Form id

        $.ajax(
            type: frm.attr('method'),
            url: '% url 'save_mapper' %',      // Url pointing to view for saving data
            data: frm.serialize(),
            success: function(data) 
                console.log('Success !!');
                console.log(data);
            ,
            error: function(data) 
                console.log('Problemo');
                console.log(data);
            ,
        );
    );
);

【问题讨论】:

你检查过 Django Rest 框架吗?它将为您节省大量时间,非常成熟且有据可查。另一方面,如果不查看您的代码,几乎不可能提供帮助。如果您可以同时包含 FBV 和模型,那么人们应该可以为您提供帮助。 @anowlinorbit - 添加了代码。同时检查 REST。 【参考方案1】:

如果我对你的理解正确,那就是你想创建一个mapTargItem 的实例,FK 指向一个mapTarg 的实例,那么我将在 DRF 中创建视图集。我将从序列化程序开始。这是 DRF 中非常常见的模式

serializers.py

from rest_framework import serializers
from .models import mapTarg, mapTargItems

class mapTargItemsSerializer(serializers.ModelSerializer):
    class Meta:
        model = mapTarg
        fields = "__all__"
        # if you want to only return a select number of model attributes
        # then you can as an example define fields as follows
        # fields = ("map_name", "map_target")

class mapTargSerializer(serializers.ModelSerializer):

    map_hdr_tab = mapTargItemsSerializer()

    class Meta:
        model = mapTarg
        fields = "__all__"

views.py

from .serializers import mapTargItemsSerializer, mapTargSerializer
from .models import mapTarg, mapTargItems


class mapTargItemsViewSet(viewsets.ModelViewSet):
    serializer_class = mapTargItemsSerializer
    permission_classes = [IsAuthenticated]
    queryset = mapTargItems.objects.all()

    # you can override get_queryset() for more advanced queries


class mapTargViewSet(viewsets.ModelViewSet):
    serializer_class = mapTargSerializer
    permission_classes = [IsAuthenticated]
    queryset = mapTarg.objects.all()

urls.py

from rest_framework.routers import SimpleRouter
from django.urls import path, include
from .views import mapTargViewSet, mapTargItemsViewSet

router = SimpleRouter(trailing_slash=False)
router.register("map_targs", mapTargViewSet, basename="map_targs")
router.register("map_targ_items", mapTargItemsViewSet, basename="map_targ_items")

urlpatterns = [
    path("", include(router.urls)),
]

您现在可以点击map_targs 的端点,获取您要用作mapTargItems 的FK 的对象,然后POST 到map_targ_items

DRF 将为您处理验证、序列化和响应,并在发生任何错误时返回合理的错误消息。

希望这会有所帮助。

【讨论】:

非常感谢您花时间写这篇文章。我将来肯定会使用它。但目前这在我目前的情况下不起作用。正如我所描述的,我正在使用 Django 表单集,我使用来自各种模型的数据来填充这些表单集。表单排列整齐,使用 jQuery 我可以在 runtime 添加额外的表单集。我会非常理解这是在相关模型中创建记录的任何 正常 Django 内联表单集场景。所以我的问题是 - 如何将这些数据(位于表单和表单集中)发送到相应的模型。

以上是关于如何使用多个 Django FBV 通过 Ajax+jQuery 捕获和保存数据的主要内容,如果未能解决你的问题,请参考以下文章

6)django-实例(fbv)

django 的cbv和fbv

我如何将 django fbv 写入基于类的视图

python(十九):django之FBV和CBV

python测试开发django-73.django视图 CBV 和 FBV

Django之请求生命周期及FBV/CBV模式