从一个整数中减去另一个整数并保存

Substract one integer from another and save

我需要用一个整数减去另一个整数并保存结果。它是某种付款方式。以前从来没有这样做过,所以下面的代码——在我看来这是我想要做的:

def checkoutstatus(request, article_id):
    if request.POST:
        article = Article.objects.filter(id=article_id) 
        article.article_users.add(request.user)

        balance = int(UserProfile.objects.filter(balance=user_balance))
        cost = int(Article.objects.filter(cost=article_cost))
        new_balance = balance - cost

        article.save()

所以我先将 User 连接到 Article 模型。然后我需要从 UserProfile 模型(用 ForeignKey 扩展 User)字段 user_balance 中减去 Article 模型字段 article_cost 并将结果保存回去至 user_balance...

正如您在上面的代码中看到的,我尝试进行减法,但是现在如何将结果保存回 user_balance

此外,如果两个模型中的两个字段都已经作为 IntegerField 使用,我是否需要 int 转换器?

我的应用程序 article:

from django.db import models
from django.contrib.auth.models import User
from django.db import models

class Article(models.Model):
    class Meta():
        db_table = 'article'

    article_users = models.ManyToManyField(User)
    article_title = models.CharField(max_length=200, blank=False, null=False)
    article_content = models.IntegerField(choices=CONTENT_CHOICES, null=True, blank=True)
    article_cost = models.IntegerField(default=0)
    article_likes = models.IntegerField(default=0)

我的应用程序 userprofile:

import PIL

from django.db import models
from django.contrib.auth.models import User
from PIL import Image
from django.db import models
from article.models import Article

class UserProfile(models.Model):  
    user = models.OneToOneField(User)
    user_picture = models.ImageField(upload_to='users', blank=False, null=False, default='users/big-avatar.jpg')
    user_balance = models.IntegerField(default=0)

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u) [0])

我还创建了一个应用程序 orderstatus,它需要在数据库中保存订单历史记录:

from django.db import models
from django.contrib.auth.models import User
from article.models import Article

class OrderHistory(models.Model):
    class Meta():
        db_table = 'order'

    user = models.ForeignKey(User)
    article = models.ForeignKey(Article)
    purchase_date = models.DateTimeField(auto_now_add=True)

并为它写一个视图(你可以在那个post的开头看到):

from django.shortcuts import render, render_to_response, redirect, Http404
from django.core.context_processors import csrf
from django.contrib import auth
from django.template import RequestContext
import datetime

from django.contrib.auth.models import User
from article.models import Article
from userprofile.models import UserProfile

def checkoutstatus(request, article_id):
    if request.POST:
        article = Article.objects.filter(id=article_id) 
        article.article_users.add(request.user)

        balance = int(UserProfile.objects.filter(balance=user_balance))
        cost = int(Article.objects.filter(cost=article_cost))
        new_balance = balance - cost

        article.save()

从 MVT(模型视图模板)的角度来看,UserProfile 的平衡修改应该在模型中处理,而不是在视图中。

class UserProfile(models.Model):

    ## fields
    balance = models.IntegerField(default=0)


    def withdraw(self, amount):
        # you will need to check here if the 
        # balance is enough for this transaction or not
        self.balance = self.balance - amount


    def can_purchase_amount(self, amount):
        return True if amount <= self.balance

views.py

def checkoutstatus(request, article_id):
    """
    Make the transaction
    """
    user_profile = UserProfile.objects.get(user=request.user)
    article = Article.objects.filter(id=article_id)


    # check if the user can purhcase this
    if user_profile.can_purchase_amount(article.article_cost):
        # the user have enough balance to make this payment
        user_profile.withdraw(article.article_cost)
        user_profile.save()

        # add the user to the article
        article.article_users.add(request.user)

        # other things like register order or log

    else:
        # no enough balance

的确,这段代码对于真钱交易来说并不完整,但它演示了谁应该做什么。您可能需要在提交交易之前锁定用户的余额,以确保没有重复。此外,您可能希望将此记录下来以备将来邀请

一种方法是重写 checkoutstatus 如下:

def checkoutstatus(request, article_id):
    if request.POST:
        article = Article.objects.filter(id=article_id) 
        article.article_users.add(request.user)

        balance = int(UserProfile.objects.filter(balance=user_balance))
        cost = int(Article.objects.filter(cost=article_cost))
        new_balance = balance - cost

        profile_to_update = UserProfile.objects.get(user=request.user)
        profile_to_update.user_balance = new_balance
        profile_to_update.save()

        article.save()

但这不是标准方式。查看@Othman 的回答以获得更好的实施思路。