Нам просто пришлось обойти эту проблему и протестировать три разных подхода.
var Ajax1 = {
call: function() {
if (typeof this.xhr !== 'undefined')
this.xhr.abort();
this.xhr = $.ajax({
url: 'your/long/running/request/path',
type: 'GET',
success: function(data) {
//process response
}
});
}
};
var Ajax2 = {
counter: 0,
call: function() {
var self = this,
seq = ++this.counter;
$.ajax({
url: 'your/long/running/request/path',
type: 'GET',
success: function(data) {
if (seq === self.counter) {
//process response
}
}
});
}
};
var Ajax3 = {
active: false,
call: function() {
if (this.active === false) {
this.active = true;
var self = this;
$.ajax({
url: 'your/long/running/request/path',
type: 'GET',
success: function(data) {
//process response
},
complete: function() {
self.active = false;
}
});
}
}
};
$(function() {
$('#button').click(function(e) {
Ajax3.call();
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="button" type="button" value="click" />
В нашем случае мы решили использовать подход №3, поскольку он создает меньшую нагрузку для сервера. Но я не уверен на 100%, если jQuery гарантирует вызов метода .complete (), это может вызвать тупиковую ситуацию. В наших тестах мы не смогли воспроизвести такую ситуацию.
Лучший и более обобщенный способ применить это состоял бы в том, чтобы обновить объект ModelSerializer с потенциальным экземпляром, если он существует. Это позволяет DRF следовать стандартным протоколам и может быть абстрагировано через модели легко.
Для хранения вещей универсальными запустите путем создания класса UpdateOrCreate, который будет наследован вместе с modelSerializer на инстанцировании. В этом добавьте определение update_or_create_helper
.
Тогда наследовались UpdateOrCreate
класс для каждого Сериализатора, с которым Вы хотите функциональность и добавляете простое is_valid
определение, характерное для той модели.
serializers.py
class UpdateOrCreate:
def update_or_create_helper(self, obj_model, pk):
# Check to see if data has been given to the serializer
if hasattr(self, 'initial_data'):
# Pull the object from the db
obj = obj_model.objects.filter(pk=self.initial_data[pk])
# Check if one and only one object exists with matching criteria
if len(obj)==1:
# If you want to allow for partial updates
self.partial = True
# Add the current instance to the object
self.instance = obj[0]
# Continue normally
return super().is_valid()
...
# Instantiate the model with your standard ModelSerializer
# Inherit the UpdateOrCreate class
class MyModelSerializer(serializers.ModelSerializer, UpdateOrCreate):
class Meta:
model = MyModel
fields = ['pk', 'other_fields']
# Extend is_valid to include the newly created update_or_create_helper
def is_valid(self):
return self.update_or_create_helper(obj_model=MyModel, pk='pk')