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)
Вернуться на верх