Django的更新/创建架构(Django update/create architecture)

2019-11-04 19:05发布

我制定了一个办法为自己如何创建和更新我的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

这里依赖于零级或多个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

对于“一个”应用程序的创建和更新的观点是:

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(一)功能保存()命令? 它似乎对这个很简单的例子,工作,但如果车型增加这样的复杂性会增加,这种方法也许不再可行?

Answer 1:

另一个也许更优雅的方式是定义A3和B3的性质,而不是将它们存储在数据库中。 这样,A3和B3在需要时立即计算。 在B型的B1和B2领域的最新情况将立即导致A3财产的新更新值。

当然,缺点是我们不能(容易)查询A3和B3的数据库,因为它们不是存储在数据库中。

该模型比定义为:

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 })

更新和创建视图的模型是:

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,)))    


文章来源: Django update/create architecture