Джанго обновить / создать архитектуру - PullRequest
0 голосов
/ 29 мая 2018

Я разработал для себя способ создания и обновления моих моделей 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 "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,)))    

Вопрос теперь в том, правильный ли это путь?Правильно ли использовать команду save () в функциях set_a (a)?Кажется, это работает для этого очень простого примера, но если модели увеличатся, сложность возрастет, и этот метод, возможно, больше не будет жизнеспособным ...

1 Ответ

0 голосов
/ 03 июня 2018

Другой, возможно, более элегантный способ - определить a3 и b3 как свойства, а не сохранять их в базе данных.Таким образом, a3 и b3 сразу вычисляются при необходимости.Обновление в полях b1 и b2 модели B немедленно приведет к новому обновленному значению свойства 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,)))    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...