Я пытаюсь выполнить update_or_create на Django, при этом также задействованы некоторые logi c (мне нужно немного отклониться от лучших практик с PUT из-за уникального характера набора символов, который я использую) .
В моем представлении есть следующий код (показывающий только метод PUT):
class WordView(APIView):
def put(self, request, user_id):
character = request.data.get('character')
correct = request.data.get('correct')
mistakes = request.data.get('mistakes')
score = request.data.get('score')
if Word.objects.filter(user_id=user_id, character=character).exists():
orig_word = Word.objects.get(user_id=user_id, character=character)
correct = correct + orig_word.correct
mistakes = mistakes + orig_word.mistakes
trials = orig_word.trials + 1
score = (score + (orig_word.score * orig_word.trials)) / trials
pk = orig_word.pk
else:
trials = 1
# Note - I know that pk won't exist on create - just testing update right now
word_saves = {"user_id": user_id, "character": character,
"correct": correct, "mistakes": mistakes, "score": score, "trials": trials, "pk": pk}
serializer = WordSerializer(data=word_saves)
if serializer.is_valid(raise_exception=True):
word_saved = serializer.save()
return Response({"success": "Word character {} saved for user {}".format(word_saved.character, word_saved.user_id)})
В любом случае в моем WordSerializer у меня есть следующее:
class WordSerializer(serializers.Serializer):
user_id = serializers.IntegerField()
character = serializers.CharField()
correct = serializers.IntegerField()
mistakes = serializers.IntegerField()
score = serializers.FloatField()
trials = serializers.IntegerField()
pk = serializers.IntegerField()
def create(self, validated_data):
return Word.objects.update_or_create(**validated_data)
Однако, когда я делаю запрос PUT, когда существует строка с данным user_id и символом, я получаю следующее:
django.db.utils.IntegrityError: (1062, "Duplicate entry '29' for key 'PRIMARY'")
Дело в том, что я хочу обновить значение, которое существует в базе данных с моим новым значением. Я предположил, что это именно то, что сделал update_or_create
- upsert.
Как мне сделать upsert с текущим кодом?