ermek6
@ermek6
::Живу с удовольствием::

Как организовать учет в django?

Всем привет! Изучаю Django. Туториал на оф. сайте прошел. Теперь разбираюсь сам :)

Делаю следующее: Хочу реализовать систему учета товаров. Товар может покупаться, оприходоваться из излишков, перемещаться между складами, продаваться, списываться в недостачу.
Соответственно есть модели Good, Stock с одним полем name (char) для справочников.

Документы состоят из двух моделей:

Document
  • date:DateTime
  • number: Char
  • stock: ForeignKey(Stock)

DocumentString
  • document:ForeignKey(Document)
  • good: ForeignKey(Good)>
  • count: Float
  • price: Float
  • sum: Float


Для того, что бы не анализировать кучу документов для отчетов, все движения по товарам должны отображаться в одной таблице, Register, где фиксируются приходы и расходы. Собственно тут у меня и затык:

Не могу определится, как лучше связать таблицы документа и регистра:

Вариант 1:
При использовании связи ManyToMany из документа при перезаписи документа необходимо удалить старые записи движений и создать новые, однако метод clear только удаляет связи, при этом не удаляя сами записи из регистра. Тут вижу следующие действия:
  1. Переопределить метод save документа. В нем:
  2. Вытащить id всех записей регистра в массив
  3. Очистить связи методом Clear
  4. По id найти все записи из регистра
  5. Удалить их методом delete
  6. Добавить новые записи согласно данным документа


Вариант 2
  1. В таблице регистра добавить 2 поля: doc_type: Char, doc_id: int
  2. Переопределить метод save документа. В нем:
  3. Найти все записи в Register соотв. текущему документу
  4. Удалить их методом delete
  5. Добавить новые записи согласно данным документа


Прошу сообщество подсказать, и если не сложно с аргументами, какой из способов лучше, или по советовать другой вариант
  • Вопрос задан
  • 713 просмотров
Решения вопроса 1
ermek6
@ermek6 Автор вопроса
::Живу с удовольствием::
В Django есть встроенный функционал, подобный которому я описал в сабже в п.2.
Используется системой аутентификации Django.

Суть в следующем:
from django.db import models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericRelation

# создадим класс, хранящий множество записей, которые могут привязываться к разным моделями
class Accumulator(models.Model):
    # Ссылка на встроенную модель, где фигурируют все модели всех зарегистрированных приложений
    content_type = models.ForeignKey(ContentType, on_delete=models.PROTECT, editable=False, db_index=True)
    # Ключ самого объекта, на который ссылаемся
    object_id = models.UUIDField(editable=False, db_index=True)
    # "Виртуальное" поле, в котором/через который взаимодействуем с объектом
    content_object = GenericForeignKey('content_type', 'object_id')
    # то, что собираем из всех моделей
    sum = models.DecimalField(max_digits=12, decimal_places=2, verbose_name='Сумма')

class CashIn(models.Model) 
    # Вопрос религиозный. Останавливаться не буду :)
    uuid = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4)
    # Что регистрирует текущая модель
    sum =  models.DecimalField(max_digits=12, decimal_places=2, verbose_name='Сумма')
    # Ссылка в объекте модели на записи
    accumulator =  GenericRelation(Accumulator)

    # Переопределяем встроенные методы. 
    # Вопрос можно решить и через сигналы. Еще смотрю
    def save(self, *args, **kwargs):
        super(CashIn, self).save(*args, **kwargs)
        self.accumulator.all().delete()
        self.accumulator.create(sum=self.sum)

    def delete(self, using=None, keep_parents=False):
        self.accumulator.all().delete()
        super(CashIn, self).delete(using=using, keep_parents=keep_parents)

# Аналогичен CashIn, но записывает в другую сторону сумму
class CashOut(models.Model)
    uuid = models.UUIDField(primary_key=True, editable=False, default=uuid.uuid4)
    sum =  models.DecimalField(max_digits=12, decimal_places=2, verbose_name='Сумма')
    accumulator =  GenericRelation(Accumulator)

    def save(self, *args, **kwargs):
        super(CashOut, self).save(*args, **kwargs)
        self.accumulator.all().delete()
        self.accumulator.create(sum=-self.sum)

    def delete(self, using=None, keep_parents=False):
        self.accumulator.all().delete()
        super(CashOut, self).delete(using=using, keep_parents=keep_parents)


После всего выше сказанного можно вытащить результат в "кассе" одной строкой, без анализа всех таблиц:
Accumulator.objects.all().aggregate(models.Sum('sum'))['sum__sum']
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
Guest007
@Guest007
Django, Python, Linux и всё такое...
Пусть этот самый Register хранит записи о движении товара. Каждая его запись это указание на то, какой товар перемещался, откуда перемещался и куда. Ну и дата/время и кто перемещал тоже можно добавить.
Всё. Register получается такой лог событий. Оттуда ничего удалять не надо. Задним числом записи редактировать - не надо. Это основы учёта. Ты всегда можешь посмотреть аналитику по товару, по складу, по времени (и по ответственному лицу, если что).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы