Есть идеи, как реализовать создание/хранение приходной/расходной накладной на Django?
В одной таблице должны храниться документы, во второй - строки табличной части (всех документов).
models.py:from django.db import models
from django.db.models import Max, Sum
from django.utils.translation import ugettext_lazy as _


class Product(models.Model):
    name = models.CharField(
        _('Name'),
        max_length=200,
        db_index=True,
    )

    def __str__(self):
        return self.name


class Document(models.Model):
    INVOICE = 'I'
    WAYBILL = 'W'
    TYPE_CHOICES = (
        (INVOICE, _('Invoice')),
        (WAYBILL, _('Waybill')),
    )
    type = models.CharField(
        _('Type'),
        max_length=1,
        choices=TYPE_CHOICES,
    )
    number = models.CharField(
        _('Number'),
        blank=True,
        max_length=50,
    )
    created_at = models.DateTimeField(
        _('Created'),
        auto_now_add=True,
        db_index=True,
    )

    @property
    def total(self):
        return self.items.aggregate(sum=Sum('total'))['sum']

    class Meta:
        ordering = ['-created_at']


class DocumentItem(models.Model):
    document = models.ForeignKey(
        Document,
        models.CASCADE,
        related_name='items',
    )
    position = models.PositiveIntegerField(
        verbose_name=_('Position'),
        editable=False,
        db_index=True,
    )
    product = models.ForeignKey(
        Product,
        models.PROTECT,
    )
    price = models.DecimalField(
        _('Price'),
        max_digits=12,
        decimal_places=2,
    )
    quantity = models.DecimalField(
        _('Quantity'),
        max_digits=10,
        decimal_places=3,
    )
    total = models.DecimalField(
        _('Total'),
        max_digits=12,
        decimal_places=2,
    )

    def save(self, *args, **kwargs):
        if not self.position:
            position = self.document.items.aggregate(Max('position'))['position__max'] or 0
            self.position = position + 1
        super(DocumentItem, self).save(*args, **kwargs)
admin.py:from django.contrib import admin

from .models import Product, Document, DocumentItem


@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    pass


class DocumentItemInline(admin.TabularInline):
    model = DocumentItem
    fields = (
        'position',
        'product',
        'price',
        'quantity',
        'total',
    )
    readonly_fields = (
        'position',
    )
    ordering = ['position']


@admin.register(Document)
class DocumentAdmin(admin.ModelAdmin):
    inlines = [
        DocumentItemInline,
    ]
    list_display = (
        'type',
        'number',
        'created_at',
        'total',
    )
    list_filter = (
        'type',
    )
    search_fields = (
        '=number',
    )
Стандартная админка - для примера, вообще она не для этого (обычным пользователям она не должна быть доступна). Но реальные формы строятся по тому же принципу.
Код накидал прям здесь, не проверял, поэтому возможны незначительные ошибки.
Я не совсем понял, акцент на том, как организовать хранения данных в мускуле или что-то, что касается именно джанги?
Если первое - я бы разделил документы на типы: еще одно поле в таблице документов, которое бы определяло тип документа (enum "sale", "order", etc.). И зная тип, документа можно"на лету" формировать те же остатки по складу, не парясь о целостности данных. А в качестве уникальных идентификаторов для позиций поставки и по ним же отслеживать что продалось со склада - использовать например md5 хеш:
product_id + order_price ("плюс" тут рассматривать как канкатонацию параметров).
Другой вопрос, что будет потом через много-много времени... Т.к. такой вариант рассчета склада "на лету" рано или поздно будет увеличивать нагрузку на субд, но тут уже индивидуальный вопрос каждого. Если это не 100500 продаж в день то данная схема вполне может существовать и успешно разруливать на протяжении долгого времени. А там видно будет:)