django - Django 更新/创建架构
问题描述
我已经为自己找到了一种方法来创建和更新我的 Django 模型。但我想知道这是否是正确的方法。假设我们有两个模型 A 和 B,其中一个 A 可以有多个 B。
这里 B 有两个用户输入 b1、b2 和“b3”定义为:b3 = b1 + b2
这里 A 也有两个用户输入字段 a1、a2 和“a3”定义为:a3 = a1 + a2 + b[0].b3 + b[1].b3 + ... + b[N].b3
这里A取决于零个或多个B。如果 B 的其中一项发生更改,则 A 将需要重新计算它的 a3 字段。
因此,A 和 B 模型定义为:
class A(models.Model):
a1 = models.FloatField(default=0)
a2 = models.FloatField(default=0)
a3 = models.FloatField(default=0)
@classmethod
def create( cls, a1, a2):
a = cls(a1 = a1, a2 = a2)
return a
def set_a(self, a):
a.a3 = a.a1 + a.a2
bs = B.objects.filter(a=a)
for b in bs:
a.a3 += b.b3
a.save()
return a
class B(models.Model):
a = models.ForeignKey('a.A', related_name='bs', on_delete=models.CASCADE)
b1 = models.FloatField(default=0)
b2 = models.FloatField(default=0)
b3 = models.FloatField(default=0)
@classmethod
def create( cls, a, b1, b2):
b = cls( a = a, b1 = b1, b2 = b2)
return b
def set_b(self, b):
b.b3 = b.b1 + b.b2
b.save()
b.a.set_a(b.a)
return b
“a”应用程序的创建和更新视图是:
class ACreateView(LoginRequiredMixin, CreateView):
model = A
template_name = 'a/create.html'
form_class = AForm
def form_valid(self, form):
a = A.create( a1 = form.cleaned_data['a1'],
a2 = form.cleaned_data['a2'])
a = a.set_a(a)
return HttpResponseRedirect(reverse('a:detail', args=(a.id,)))
class AUpdateView(LoginRequiredMixin, UpdateView):
model = A
template_name = 'a/detail-update.html'
form_class = AForm
def get_object(self):
return get_object_or_404(A, pk=self.kwargs['pk_a'])
def form_valid(self, form):
a = self.get_object()
a.a1 = form.cleaned_data['a1']
a.a2 = form.cleaned_data['a2']
a = a.set_a(a)
return HttpResponseRedirect(reverse('a:detail', args=(a.id,)))
现在的问题是这是正确的方法吗?在 set_a(a) 函数中使用 save() 命令是否正确?它似乎适用于这个非常简单的例子,但如果模型增加,那么复杂性就会增加,这种方法可能不再可行......
解决方案
另一种可能更优雅的方法是将 a3 和 b3 定义为属性,而不是将它们存储在数据库中。这样 a3 和 b3 会在需要时立即计算出来。B 模型的 b1 和 b2 字段的更新将立即导致 a3 属性的新更新值。
当然,缺点是我们不能(轻松)在数据库中查询 a3 和 b3,因为它们没有存储在数据库中。
A 模型被定义为:
from django.db import models
from b.models import B
class A(models.Model):
a_name = models.CharField(max_length=200)
a1 = models.FloatField(default=0)
a2 = models.FloatField(default=0)
@classmethod
def create( cls, a_name, a1, a2):
a = cls( a_name = a_name, a1 = a1, a2 = a2)
b1 = B.create(a = a, b_name = "auto_created_b1", b1 = 999, b2=0)
return a
@property
def a3(self):
a3 = self.a1 + self.a2
bs = B.objects.filter(a=self)
for b in bs:
a3 += b.b3
return a3
def get_absolute_url(self):
return reverse('a:detail', kwargs={'pk_a':self.id })
A 模型的更新和创建视图是:
class ACreateView(LoginRequiredMixin, CreateView):
model = A
template_name = 'a/create.html'
form_class = AForm
def form_valid(self, form):
a = A.create( a_name = form.cleaned_data['a_name'],
a1 = form.cleaned_data['a1'],
a2 = form.cleaned_data['a2'])
a.save()
return HttpResponseRedirect(reverse('a:detail', args=(a.id,)))
class AUpdateView(LoginRequiredMixin, UpdateView):
model = A
template_name = 'a/detail-update.html'
form_class = AForm
def get_object(self):
return get_object_or_404(A, pk=self.kwargs['pk_a'])
def form_valid(self, form):
a = self.get_object()
a.a_name = form.cleaned_data['a_name']
a.a1 = form.cleaned_data['a1']
a.a2 = form.cleaned_data['a2']
a.save()
return HttpResponseRedirect(reverse('a:detail', args=(a.id,)))
推荐阅读
- python - 尝试使用 matplotlib 绘图时不断出现错误
- tensorflow - NotFoundError:[_Derived_]没有为操作定义梯度:Tensorflow 1.15.0 上的 StatefulPartitionedCall
- c# - 尝试激活时无法解析“System.Net.Http.HttpClient”类型的服务
- python-3.x - 如何将 Python SQLAlchemy ORM 与 MonetDB 和数据库模式一起使用
- python - 用坐标绘制 NetworkX Graph
- json - 发送和接收文件的 Python 格式问题
- r - 如何使用 mutate 创建一个变量,该变量将为我提供 R 中一周的日期?
- reactjs - 浏览时出现白屏
- javascript - 使用虚拟键盘时 useState 的初始值未更新
- r - 在 Shiny 中,如果所选变量是数字变量,如何输出直方图,如果是分类变量,如何输出条形图?