如何在基于 Django class 的视图中执行计算?

How to perform calculations in Django class-based views?

我使用基于 Django class 的视图创建了一个简单的 Web 应用程序。在此应用程序中,用户提交建筑物的长度和宽度,应用程序计算面积并将其存储在数据库中。提交后,用户将被重定向到 'results' 页面,他可以在其中查看他的输入和结果。

我不知道如何在通用视图中实现这样的计算功能。

我的模特:

from django.db import models


class Building(models.Model):

    length = models.IntegerField(default=1)
    width = models.IntegerField(default=1)
    area = models.IntegerField(default=1)

    def __str__(self):
        return self.name

我的表格:

from django import forms
from .models import Building

class BuildingForm(forms.ModelForm):
    class Meta:
        model = Building
        fields = ('length', 'width', 'area')

我的观点:

from django.views.generic import ListView, CreateView, UpdateView
from django.urls import reverse, reverse_lazy
from .models import Building
from .forms import BuildingForm
from django.http import HttpResponseRedirect, HttpResponse


class BuildingListView(ListView):
    model = Building
    context_object_name = 'buildings'


class BuildingCreateView(CreateView):
    model = Building
    form_class = BuildingForm
    success_url = reverse_lazy('results')


class BuildingUpdateView(UpdateView):
    model = Building
    form_class = BuildingForm
    success_url = reverse_lazy('building_changelist')


def calculation(request):

    length = request.POST.get('length', False)
    width = request.POST.get('width', False)
    area = length * width
    Building.objects.create(length=length, width=width, area=area,)

    return HttpResponseRedirect(reverse('results'))

有人可以分享一个与我的问题相关的好例子,或者帮助我在我的视图文件中实现这个功能吗?

您可以在 .form_is_valid() 方法中执行此操作:

class BuildingCreateView(CreateView):
    model = Building
    form_class = BuildingForm
    success_url = reverse_lazy('results')

    def form_valid(self, form):
        resp = super().form_valid(form)
        form.instance.area = form.length * form.width
        form.save()
        return resp

不过在模型里面做计算还是不错的(每次保存模型都会保存面积):

class Building(models.Model):

    length = models.IntegerField(default=1)
    width = models.IntegerField(default=1)
    area = models.IntegerField(default=1)

    def __str__(self):
       return self.name

    def save(self, *args, **kwargs):
       self.area = self.length * self.width 
       super().save(*args, **kwargs)

甚至让它在每次调用时都计算,而不需要将它保存到数据库中:

class Building(models.Model):

    length = models.IntegerField(default=1)
    width = models.IntegerField(default=1)

    def __str__(self):
       return self.name

    @property
    def area(self):
       return self.lenght * self.width