我在我的Django 4 web应用中使用js和django view函数实现了自动保存功能,但它会每隔一段时间保存新的模型示例

6jygbczu  于 12个月前  发布在  Go
关注(0)|答案(1)|浏览(121)

我已经在我的Django 4 Web应用程序中实现了自动保存功能,使用JavaScript和Django views.py函数作为端点。我让它保存表单/模型示例到数据库,绕过Django表单验证。现在的问题是它在每隔一段时间都会保存新的示例。
正确的行为是创建第一个示例,并且在随后的时间间隔中,如果自上次自动保存以来有更改,则仅使用新数据更新数据库。
问题是我不知道如何存储刚刚创建的模型示例的id,这样在每次调用auto保存JavaScript时,我就可以检查这个auto保存请求是一个新的请求还是一个现有的请求。在这一点上我还没有尝试过任何东西。让我可以保存未经检查的表单/模型示例已经花了我很多时间。
下面是java script:

$(document).ready(function() {
  var lastSavedData = $('#dormForm').serialize(); // Serialize the initial form data

  function autoSave() {
      var currentData = $('#dormForm').serialize(); // Serialize the current form data

      // Check if the current data is different from the last saved data
      if (currentData !== lastSavedData) {
          $.ajax({
              url: '/autosave/',
              type: 'POST',
              data: currentData,
              success: function(response) {
                  if (response.status === 'success') {
                      console.log('Data saved');
                      lastSavedData = currentData; // Update lastSavedData with the new data
                  } else {
                      console.log('Error during auto save.');
                  }
              },
              error: function() {
                  console.log('Error during auto save.');
              }
          });
      } else {
          console.log('No changes to save.');
      }
  }

  setInterval(autoSave, 30000); // Trigger the autoSave function every 30 seconds
});

字符串
这是django 4 views.py函数:

@require_POST
def auto_save(request):
    # Get the last saved instance ID from the session
    last_saved_instance_id = request.session.get('last_saved_instance_id')

    responses = {}

    # Check if last_saved_instance_id exists and retrieve the instance
    if last_saved_instance_id:
        instance = get_object_or_404(LossEventPage1, pk=last_saved_instance_id)
    else:
        instance = LossEventPage1()  # Create a new instance

    # Instantiate LossEventPage1Form with the POST data and the retrieved instance
    form_one = LossEventPage1Form(request.POST, request.FILES, instance=instance)

    if request.method == "POST":
        for field_name in form_one.fields:
            field = form_one.fields[field_name]
            try:
                if field_name in request.POST or field_name in request.FILES:
                    # For files, use FILES, for other data, use POST
                    field_value = request.FILES.get(field_name) if isinstance(field, forms.FileField) else request.POST.get(field_name)
                    if field_value is not None:
                        # Clean and save the value for the field
                        field_value = field.clean(field_value)
                        setattr(instance, field_name, field_value)
                elif field.required:
                    # If the field is required and not in POST, return an error response
                    responses['form_one'] = {
                        'status': 'error',
                        'reason': f'Missing required field: {field_name}'
                    }
                    continue  # Skip saving this instance
            except ValidationError as e:
                # If validation fails, return an error response
                responses['form_one'] = {
                    'status': 'error',
                    'reason': f'Validation error on field {field_name}: {e.messages}'
                }
                continue  # Skip saving this instance

        instance.is_draft = True  # Set draft flag
        instance.save()  # Save the instance without calling form.save()

        # You might need to handle the setting of ManyToMany fields here, after saving the instance

        if 'form_one' not in responses:
            responses['form_one'] = {'status': 'success'}
    else:
        responses['form_one'] = {'status': 'skipped', 'reason': 'No data to save for form_one'}

    # Query related models and update their instances if they exist
    related_models = [LossEventPage2, LossEventPage4, LossEventPage5]

    for related_model in related_models:
        # Query the related model's one-to-one field to find the associated instance
        related_instance = related_model.objects.filter(lossEventPage1=instance).first()

        # Instantiate the related model's form with the POST data and the retrieved related instance
        form = related_model.form_class(request.POST, request.FILES, instance=related_instance)

        if request.method == "POST":
            for field_name in form.fields:
                field = form.fields[field_name]
                try:
                    if field_name in request.POST or field_name in request.FILES:
                        # For files, use FILES, for other data, use POST
                        field_value = request.FILES.get(field_name) if isinstance(field, forms.FileField) else request.POST.get(field_name)
                        if field_value is not None:
                            # Clean and save the value for the field
                            field_value = field.clean(field_value)
                            setattr(related_instance, field_name, field_value)
                    elif field.required:
                        # If the field is required and not in POST, return an error response
                        responses[related_model.__name__] = {
                            'status': 'error',
                            'reason': f'Missing required field: {field_name}'
                        }
                        continue  # Skip saving this instance
                except ValidationError as e:
                    # If validation fails, return an error response
                    responses[related_model.__name__] = {
                        'status': 'error',
                        'reason': f'Validation error on field {field_name}: {e.messages}'
                    }
                    continue  # Skip saving this instance

            if related_instance:
                related_instance.save()  # Save the related instance

            if related_model.__name__ not in responses:
                responses[related_model.__name__] = {'status': 'success'}
        else:
            responses[related_model.__name__] = {'status': 'skipped', 'reason': f'No data to save for {related_model.__name__}'}

    return JsonResponse(responses)

6yjfywim

6yjfywim1#

要实现您所描述的行为,即您只希望在自上次自动保存以来发生更改时创建新示例,您可以执行以下步骤:

**1.保存上次保存的示例ID:**初始创建示例时,需要将创建的示例ID保存在session变量、cookie或客户端的JavaScript变量中,本例中使用session变量。

在你的Django视图中,你第一次保存示例:

request.session['last_saved_instance_id'] = instance.id

字符串

**2.修改JavaScript以检查更改:**在JavaScript中,您需要将表单数据与上次保存的数据进行比较,以确定是否进行了更改。如果进行了更改,则发送自动保存请求,否则跳过它。

下面是一段经过修改的JavaScript代码,帮助您入门:

$(document).ready(function() {
    var lastSavedData = $('#dormForm').serialize(); // Serialize the initial form data

    function autoSave() {
        var currentData = $('#dormForm').serialize(); // Serialize the current form data

        // Check if the current data is different from the last saved data
        if (currentData !== lastSavedData) {
            $.ajax({
                url: '/autosave/',
                type: 'POST',
                data: currentData,
                success: function(response) {
                    if (response.status === 'success') {
                        console.log('Data saved');
                        lastSavedData = currentData; // Update lastSavedData with the new data
                    } else {
                        console.log('Error during auto save.');
                    }
                },
                error: function() {
                    console.log('Error during auto save.');
                }
            });
        } else {
            console.log('No changes to save.');
        }
    }

    setInterval(autoSave, 30000); // Trigger the autoSave function every 30 seconds
});

**3.修改Django视图以处理自动保存:**在Django视图中,您应该检查发布的数据是否与数据库中已经存储的数据不同。如果有更改,请更新现有示例,否则,不做任何操作。

您的视图应该看起来像这样:

@require_POST
def auto_save(request):
    # Get the last saved instance ID from the session
    last_saved_instance_id = request.session.get('last_saved_instance_id')

    responses = {}

    # Check if last_saved_instance_id exists and retrieve the instance
    if last_saved_instance_id:
        instance = get_object_or_404(YourModel, pk=last_saved_instance_id)
    else:
        instance = YourModel()  # Create a new instance

    # ... (your existing code for populating and saving fields)

    instance.save()  # Save the instance without calling form.save()

    # ... (your code for handling ManyToMany fields, if needed)

    responses['status'] = 'success'

    return JsonResponse(responses)


这种方法应该可以帮助您实现所需的行为,即只有在自上次自动保存以来发生了更改时才创建新示例。

相关问题