本文介绍了Django 更新/创建架构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经为自己找到了一种方法来创建和更新我的 Django 模型.但我想知道这是否是正确的方法.假设我们有两个模型 A 和 B,其中一个 A 可以有多个 B.

I have worked out a way for myself how to create and update my Django models. But I am wondering if this is the correct way. Let's say we have two models A and B, where one A can have many B's.

这里 B 有两个用户输入 b1、b2 和b3"定义为:b3 = b1 + b2

Here B has two user inputs b1, b2 and "b3" is defined as: b3 = b1 + b2

这里A也有两个用户输入字段a1、a2和a3"定义为:a3 = a1 + a2 + b[0].b3 + b[1].b3 + ... + b[N].b3

Here A also has two user input fields a1, a2 and "a3" is defined as:a3 = a1 + a2 + b[0].b3 + b[1].b3 + ... + b[N].b3

这里 A 取决于零个或多个 B.如果 B 中的一个发生变化,那么 A 将需要重新计算它的 a3 字段.

Here A depends on the zero or more B's. If one of the B's changes, than A will need to recalculate it's a3 field.

A 和 B 模型因此定义为:

The A and B models are therefore defined as:

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"应用的创建和更新视图是:

The create and update views for the "a" app are:

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() 命令是否正确?它似乎适用于这个非常简单的例子,但如果模型增加,那么复杂性就会增加,这种方法可能不再可行......

The question is now is this the correct way? Is it correct to have the save() command in the set_a(a) functions? It seems to work for this very simple example but if the models increase so the complexity will increase and this method is perhaps no longer viable...

推荐答案

另一种可能更优雅的方法是将 a3 和 b3 定义为属性,而不是将它们存储在数据库中.这样 a3 和 b3 会在需要时立即计算.B 模型的 b1 和 b2 字段中的更新将立即导致 a3 属性的新更新值.

Another perhaps more elegant way is to define a3 and b3 as properties and not store them in the database. This way a3 and b3 are immediately calculated when needed. An update in the b1 and b2 fields of the B model will immediately result in a new updated value of the a3 property.

当然缺点是我们不能(轻松)查询数据库中的 a3 和 b3,因为它们没有存储在数据库中.

Of course the disadvantage is that we cannot (easily) query the database for a3 and b3 since they are not stored in the database.

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 模型的更新和创建视图是:

The update and create views for the A model is:

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 更新/创建架构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-31 12:08