新的数据条目会覆盖列中所有过去的条目,我该如何更正?

Posted

技术标签:

【中文标题】新的数据条目会覆盖列中所有过去的条目,我该如何更正?【英文标题】:New Entry of Data overwrites all past entries in column , how do i correct this? 【发布时间】:2021-05-01 22:41:22 【问题描述】:

使用 Django,

当用户填写网络表单时,其中一个保存的数据会覆盖该列的所有传递输入数据。如何阻止它覆盖该列的其他过去数据?

Models.py 文件如下,

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




class ansquestions(models.Model):
    m_invested = models.CharField(max_length=100)
    p_return = models.CharField(max_length=100)
    years = models.CharField(max_length=100)
    inflation_yes_no = models.CharField(max_length=100)
    date_answered = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    results = models.ForeignKey('results', on_delete=models.CASCADE, null=True) # null=True
    

    
    def __str__(self):
        return self.m_invested + ' ' +self.p_return




class results(models.Model): # second table for output and add other data from ansquestions table as foreign keys
    r_output = models.CharField(max_length=500)
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    def __str__(self):
        return self.r_output
    # Important : this dunder method above __str__(self) for r_ouptput was how the actual r_output value gets displayed on admin interface. important since it was foreign key

这是前 2 个视图函数

# functions investmenttest and add are together 
def investmenttest(request):
    return render(request, 'fvalueapp/investmenttest.html')


# functions investmentfv and investmentfvcalc (real application)
# the html files that im using and have the css on them are home.html , about.html , investmentfv.html , fvinvestmentcalcresults.html(this outputs the result answer, as you see function below)  
# CSS files are under the static folder , sub-folder "design"
def investmentfv(request):
    global total_i
    global perc_r
    global years_i
    global makeup_infl
    idata =  'tmi':tmi, 'pry':pry, 'ys':ys, 'qinf':qinf 
    if request.method == "POST":

        form = AnsquestionsForm(request.POST or None)
        if form.is_valid():
            total_i = request.POST.get("m_invested", '')
            perc_r = request.POST.get("p_return", '')
            years_i = request.POST.get("years", '')
            makeup_infl = request.POST.get("inflation_yes_no", '')        
            newdata=ansquestions(m_invested=total_i, p_return=perc_r, years=years_i, inflation_yes_no=makeup_infl) 
            #newdata.results = results.objects.latest('id')#Note latest() is query set operator. BK# results.objects.order_by( 'author', 'id', 'r_output').last()#this is method for getting latest r_output from results table                                         
            newdata.author = request.user         
            newdata.save()

            return redirect('formulafv')# redirects to formulafv view function below. 'formulafv' is the name variable for that url pattern.
    else:
        return render(request, 'fvalueapp/investmentfv.html', idata)
    
    idata =  'tmi':tmi, 'pry':pry, 'ys':ys, 'qinf':qinf, 'form': form 
    return render(request, 'fvalueapp/investmentfv.html', idata)

下面是我遇到问题的视图函数,这是我在使用 latest.objects('id') 命令时遇到问题的地方,我发现这是一个解决方案,但它覆盖了所有行那个“结果”栏

def formulafv(request): 
    if makeup_infl=='no':
        i_return = (float(perc_r))
    elif makeup_infl=='yes' and int(years_i)<=5:
        i_return = (2+float(perc_r))
    elif makeup_infl=='yes' and int(years_i)>5 and int(years_i)<=9.99 :
        i_return = (4 + float(perc_r))
    elif makeup_infl=='yes' and int(years_i)>= 10 :
        i_return = ( 6 + float(perc_r))

    fv_i_value = int(total_i) * (1 + (i_return)*.01) ** int(years_i)

    r_output = 'Your money would grow to the total of ' + str(fv_i_value) +' dollars at the end of this timeframe.' 

    if request.method == "POST": # second pre-filled html form for saving r_output. for right now have to press submit button on screen. (i would want this to automatically (save/submit).      
        tom = ResForm(request.POST or None)
        if tom.is_valid():
            r_output = request.POST.get("r_output", '')
            bamdata = results(r_output=r_output)
            bamdata.author = request.user
            bamdata.save()
            
          
           
            ansquestions.results = results.objects.latest('id')  
            
            dabby = ansquestions.results 
            dabby.author = request.user 
            dabby.save()
   
   

     finalcalc = 'r_output': r_output 
     return render (request,'fvalueapp/fvinvestmentcalcresults.html', finalcalc)

【问题讨论】:

您的视图有太多的全局变量,无法读取。 不要在视图中使用全局变量,在数据库中存储任何必要的数据!即使是不断变化的唯一值,您也可以将它们存储在只有一行的表中。什么是ansquestions(全局变量)? 哦,这是你的模型名称,作为另一个注释,因为模型是用 Pascal Case 命名它们的类,如果你给它们小写名称,真的很难将它们与变量区分开来。 @AbdulAzizBarkat 我已经添加了上面的前 2 个视图函数,如果这也有助于澄清事情的话。谢谢, 我不认为你已经把完整的formulafv视图放在了那个视图中ansquestions.results = ...,你在期待什么? ansquestions 是您的模型(不是模型的实例)为什么要在模型上设置 results 属性? @AbdulAzizBarkat ,在 ansquestions.results = .... 中,我试图从上面的“结果模型”中的“r_output”字段中输入最新值。问题是它会用最近的“r_output”覆盖过去的条目。 【参考方案1】:

我看了你的问题。 首先,在 cmets 中已经提到了两件事:

    摆脱全局变量。全局变量会在 Django 应用程序中以意想不到的方式表现,除非你真的、真的、真的知道自己在做什么,否则不应该使用它们。 将您的班级名称大写,即 Ansquestions 和 Results

不碍事。让我们试着弄清楚这里发生了什么。我的理解是你想收集一些关于投资的信息,然后计算回报。

为什么结果是一个单独的模型?它可能是您的 Ansquestions 中的一个字段。您可以存储要显示的字符串,甚至更好的是,只存储数值。

为什么公式是一个单独的视图?您可以在收到输入后立即进行计算。

results.objects.latest('id') 确实会给你最新的对象。但是一旦您有多个用户访问您的应用程序,您就会遇到竞争条件,因此您会从不同的用户那里获得结果。但无论如何你在这里并不需要它。

不要直接使用request.POST,使用form.cleaned_data。如果您的 AnsquestionsForm 使用 FloatFields 和 IntegerFields,则 form.cleaned_data 将包含浮点数和整数。然后,您不需要在公式中从 str 到 int 进行任何转换

这里有一些(未经测试的)代码来说明我的意思:

# models.py
class Ansquestions(models.Model):
    m_invested = models.CharField(max_length=100)
    p_return = models.CharField(max_length=100)
    years = models.CharField(max_length=100)
    inflation_yes_no = models.CharField(max_length=100)
    date_answered = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    results = models.FloatField()

    @property
    def investment_return(self):
        return 'Your money would grow to the total of  dollars at the end of this timeframe.'.format(self.results)

# views.py
def investmentfv(request):
    idata =  'tmi':tmi, 'pry':pry, 'ys':ys, 'qinf':qinf 
    if request.method == "POST":

        form = AnsquestionsForm(request.POST or None)
        if form.is_valid():
            total_i = form.cleaned_data['m_invested']
            perc_r = form.cleaned_data["p_return"]
            years_i = form.cleaned_data["years"]
            makeup_infl = form.cleaned_data["inflation_yes_no"]
            results = formulafv(makeup_infl, years_i, perc_r, total_i)
            newdata=ansquestions(m_invested=total_i, p_return=perc_r, years=years_i, inflation_yes_no=makeup_infl, results=results) 
            newdata.author = request.user         
            newdata.save()

            return redirect('formulafv')# redirects to formulafv view function below. 'formulafv' is the name variable for that url pattern.
    else:
        return render(request, 'fvalueapp/investmentfv.html', idata)
    
    idata =  'tmi':tmi, 'pry':pry, 'ys':ys, 'qinf':qinf, 'form': form 
    return render(request, 'fvalueapp/investmentfv.html', idata)

def formulafv(makeup_infl, years_i, perc_r, total_i):
    if makeup_infl=='no':
        i_return = perc_r
    elif makeup_infl=='yes' and years_i<=5:
        i_return = 2 + perc_r
    elif makeup_infl=='yes' and years_i>5 and years_i<=9.99 :
        i_return = 4 + perc_r
    elif makeup_infl=='yes' and years_i>= 10 :
        i_return = 6 + perc_r

    fv_i_value = total_i * (1 + (i_return)*.01) ** years_i

    return fv_i_value

# admin.py
class AnsquestionAdmin(admin.ModelAdmin):
    list_display = [..., 'investment_return', ...]

另外,我建议在模型、表单和视图中为字段/变量使用相同的名称。这使得更容易理解正在发生的事情。我没有在上面的代码中这样做,以不完全改变一切。

我希望这会为您指明正确的方向。

【讨论】:

以上是关于新的数据条目会覆盖列中所有过去的条目,我该如何更正?的主要内容,如果未能解决你的问题,请参考以下文章

如果 spark 数据框的特定列中的所有条目都为空,则删除

如何在 GQL 中查询过去 6 小时(日期时间)的所有条目?

如何使用 Propel ORM 在数据库中查找重复条目?

如何使列中的条目显示为行标题

如何清空 Recyclerview数据

如何使用 R 而不是整个数据表更改 excel 文件中的单个条目?