Django update_or_create()
Я пытаюсь использовать Django update_or_create(), но не смог передать pk (obj_key) в defaults. Идея в том, чтобы фильтровать по user_id и wallet_id и обновлять, если существует, или создавать, если нет.
class ModelSelectedWallet(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
wallet = models.name = models.ForeignKey(ModelWallet, default=1, on_delete=models.CASCADE)
created = models.DateField(verbose_name='Created', auto_now_add=True)
modified = models.DateField(verbose_name='Modified', auto_now=True)
created_by = models.ForeignKey('auth.User', related_name='selected_wallet_created_by', blank=True, null=True, default=None, on_delete=models.SET_DEFAULT)
modified_by = models.ForeignKey('auth.User', related_name='selected_wallet_modified_by', blank=True, null=True, default=None, on_delete=models.SET_DEFAULT)
def select_wallet(request):
if request.method == "POST":
wallet_id = request.POST['wallet_id']
user = get_current_user()
user_id = user.id
db = ModelSelectedWallet
obj_key = db.objects.filter(user_id__exact=user_id, wallet_id__exact=wallet_id).values('id')[0]['id']
defaults = {'id': obj_key}
try:
obj = db.objects.get(user_id=user_id, wallet_id=wallet_id)
for key, value in defaults.items():
setattr(obj, key, value)
obj.save()
except db.DoesNotExist:
new_values = {
'created': datetime.datetime.now().strftime ("%Y-%m-%d"),
'created_by_id': user_id,
'modified_by_id': user_id,
'wallet_id': wallet_id,
'user_id': user_id
}
new_values.update(defaults)
obj = db(**new_values)
obj.save()
Вы можете попробовать objects.get_or_create()
. Это возьмет ваши объекты User
и Wallet
и запросит их из БД. Если они существуют, они назначаются на obj
, а created
устанавливается на False
. Если для данного пользователя и кошелька не существует объектов, то создается новый объект (obj
) и created
устанавливается в True
. Затем вы можете вносить в модель obj
любые необходимые вам правки. Это избавляет от необходимости использовать try
.
class ModelSelectedWallet(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
wallet = models.ForeignKey(ModelWallet, default=1, on_delete=models.CASCADE)
created = models.DateField(verbose_name='Created', auto_now_add=True)
modified = models.DateField(verbose_name='Modified', auto_now=True)
created_by = models.ForeignKey('auth.User', related_name='selected_wallet_created_by', blank=True, null=True, default=None, on_delete=models.SET_DEFAULT)
modified_by = models.ForeignKey('auth.User', related_name='selected_wallet_modified_by', blank=True, null=True, default=None, on_delete=models.SET_DEFAULT)
def select_wallet(request):
if request.method == "POST":
wallet_id = request.POST['wallet_id']
user = get_current_user()
wallet = Wallet.objects.get(id=wallet_id) # import Wallet from models.py
obj, created = ModelSelectedWallet.objects.get_or_create(user=user, wallet=wallet)
if created:
obj.created_by = user
obj.modified_by = user
obj.save()
else:
pass # do any updates you need here. pass is simply a command to skip this else. Replace with what you need to update.
Обратите внимание, что соглашение об именовании моделей выглядит так же, как у вас, но без "Model" - поэтому вам следует написать SelectedWallet
и Wallet
и повторно запустить миграции.
На данный момент я сделал это. Если у кого-то есть другой способ реализовать условие вставки, используя стандарт Django, пожалуйста, прокомментируйте здесь.
def select_wallet(request):
if request.method == "POST":
wallet = request.POST['wallet_id']
user = get_current_user()
created_time = datetime.datetime.now().strftime ("%Y-%m-%d")
defaults = {
'created': created_time,
'created_by_id': user,
'modified_by_id': user,
'user_id': user,
'wallet_id': wallet
}
try:
obj = SelectedWallet.objects.get(user_id=user)
for key, value in defaults.items():
setattr(obj, key, value)
obj.save()
except SelectedWallet.DoesNotExist:
created = created_time
modified = created_time
created_by_id = user.id
modified_by_id = user.id
user_id = user.id
wallet_id = wallet
with connection.cursor() as cursor:
cursor.execute('INSERT INTO `myapp`.`myapp_selected_wallet` (created, modified, created_by_id, modified_by_id, user_id, wallet_id) VALUES(%s, %s, %s, %s, %s, %s)', [created, modified, created_by_id, modified_by_id, user_id, wallet_id])
selected_wallet = (SelectedWallet.objects
.filter(user_id=user)
.filter(wallet_id=wallet)
)
return JsonResponse(list(selected_wallet.values('wallet_id')), safe = False)