我已经在我的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)
型
1条答案
按热度按时间6yjfywim1#
要实现您所描述的行为,即您只希望在自上次自动保存以来发生更改时创建新示例,您可以执行以下步骤:
**1.保存上次保存的示例ID:**初始创建示例时,需要将创建的示例ID保存在session变量、cookie或客户端的JavaScript变量中,本例中使用session变量。
在你的Django视图中,你第一次保存示例:
字符串
**2.修改JavaScript以检查更改:**在JavaScript中,您需要将表单数据与上次保存的数据进行比较,以确定是否进行了更改。如果进行了更改,则发送自动保存请求,否则跳过它。
下面是一段经过修改的JavaScript代码,帮助您入门:
型
**3.修改Django视图以处理自动保存:**在Django视图中,您应该检查发布的数据是否与数据库中已经存储的数据不同。如果有更改,请更新现有示例,否则,不做任何操作。
您的视图应该看起来像这样:
型
这种方法应该可以帮助您实现所需的行为,即只有在自上次自动保存以来发生了更改时才创建新示例。