Django:提交表单后获取最新的数据库对象值

时间:2019-02-06 09:47:36

标签: django django-models django-forms

我有一个将三个输入值保存到数据库中的表格,即1)数字,2)颜色,3)品牌。 按“提交”后,另一个例程应立即显示这些值。

问题是我无法显示最新值,但是,一旦初始分配了这些值,它们就不会更新并坚持使用第一个分配的值。

试图解决这个问题,帖子建议更新对象,例如Django Get Latest Entry from Database,我创建了一个函数,在按下Submit之后我在视图中调用了该函数,但是没有运气。

from django.forms import ModelForm
from django.views.generic import FormView
from django.urls import path, include
from django.urls import reverse


class Product(models.Model):
    number = models.CharField(max_length=10)
    color = models.CharField(max_length=10)
    make = models.CharField(max_length=10)

    objects = models.Manager()

class ProductModelForm(ModelForm):
    class Meta:
        model = Product
        fields = ('__all__')


def database():
    dbo = Product.objects.latest('id')
    dbo.refresh_from_db()
    return dbo


class ProductFormView(FormView):
    form_class = ProductModelForm
    template_name = 'form/test_form.html'

    def form_valid(self, form):
        form.save()
        return super().form_valid(form)

    def get_success_url(self):
        database()
        print(Product.objects.latest('id'))  # just as a test
        return reverse('product')



urlpatterns = [
    path('', ProductFormView.as_view(), name='product'),
]

# <!DOCTYPE html>
# <html lang="en">
# <head>
#     <meta charset="UTF-8">
#     <title>Title</title>
# </head>
# <body>
# <form method="post" >
#     {% csrf_token %}
#     {{form}}
#     <button type="submit" class="btn btn-default">Submit</button>
# </form>
# </body>
# </html>

我有一个简单的例程(db_connector.py),我在数据库对象和变量之间创建了一个链接,例如(没有任何函数或类):

number = database().number
color = database().color
make = database().make

这可能是错误的方法,但是反映了(可能是幼稚的)尝试最小化数据库请求,并提出了请求一个对象然后将该对象拆分为多个部分并链接到各个部分的想法。

问题是:

  • 我将更新表单中的所有值,然后按Submit(起作用),此最新条目现在位于数据库的“顶部”。我想检索此对象(“ number”,“ color”和“ make”的最新输入值。但是,我没有给这个对象,而是得到了一个较早的对象。尽管试图“刷新”链接的对象(产品.objects.latest('id'))停留在较早的输入(第一个输入)上。

问题是:

  • 我应该怎么做,以确保在我按表单上的Submit(具有更新的值)后始终获取最新的输入值?

2 个答案:

答案 0 :(得分:1)

尽管您提供的代码还不够imo,但我会尽力帮助和解释。

根据我的理解(从未使用过refresh_from_db),您不能以这种方式使用refresh_from_db

database()函数中,您获得了最后一个条目,并尝试刷新其信息,尽管自获得以来您并未对其进行任何更改,使其成为毫无意义的一行(它不会刷新查询,但是结果返回实例)。

refresh_from_db()更新特定实例信息(如果已从数据库获取和使用之间进行了更改)。

根据docs中的示例:

def test_update_result(self):
    obj = MyModel.objects.create(val=1)
    MyModel.objects.filter(pk=obj.pk).update(val=F('val') + 1)
    # At this point obj.val is still 1, but the value in the database
    # was updated to 2. The object's updated value needs to be reloaded
    # from the database.
    obj.refresh_from_db()
    self.assertEqual(obj.val, 2)

它根本没有按照您的想象做。

您的“提交”按钮应该在相对类视图中调用post方法,或者是将这些值保存到数据库中的某个函数(您自己也提到过)。
在反转视图函数或类中,您可以编写在datebase()-Product.objects.latest('id')中编写的查询。

此外,您可以添加诸如return reverse('product', kwargs={'lastprod': Product.objects.latest('id')})之类的附加信息。

让我知道这是否还不够清楚。

答案 1 :(得分:1)

  

我有一个将三个输入值保存到数据库的表格,1)数字,   2)颜色,3)制造。我按“提交”后,另一个例程应该   立即显示这些值。

     

问题是我无法显示最新值

您做错了(比必须做的要复杂得多)。正确的解决方案是将产品的ID明确传递给您的“产品”视图(通过url),然后在视图中重新加载对象(使用yourmodel.objects.get(pk=...))。如果您使用模型表单来创建记录,form.save()将返回新记录,以便您此时 do 拥有ID(并且,如果您仅更新现有产品,则您显然已经知道了ID)。

您没有发布足够的代码/信息来从技术上解释为什么您会出现这种行为,但是我强烈怀疑您使用的是全局变量(或类属性),这是Django项目中陈旧数据的最常见原因。

此外,请注意,在刚从db中获取的模型实例上调用“ refresh_from_db()”主要是没有用的(两次调用之间对其进行更新的机会相当渺茫),并且考虑到您的(名字不佳)“数据库”功能得以实现,这:

number = database().number
color = database().color
make = database().make

最终对数据库进行了六个 6 )查询。