0

私が自分自身を説明できるかどうか見てみましょう.私はこのモデルを持っています:

class BillHeader(models.Model):
    number = models.CharField(_('Bill number'), max_length=10, unique=True, \
    default=__number)
    client = models.ForeignKey(ClienteYProveedor, verbose_name=_('Client'))
    date = models.DateTimeField(_('Date'), default=datetime.now)

    def __unicode__(self):
        return str(self.number)

    class Meta:
        abstract = True

class BillFooter(models.Model):           
    base_import = models.DecimalField(_('Base import'), max_digits=12, \
    decimal_places=2)

    class Meta:
        abstract = True

class BillBody(models.Model):        
    description = models.CharField(_('Description'), max_length=200)
    amount = models.DecimalField(_('Amount'), max_digits=6, decimal_places=2)
    discount = models.DecimalField(_('Discount'), max_digits=4, \
    decimal_places=2)
    price = models.DecimalField(_('Price'), max_digits=12, decimal_places=2)
    unitaryprice = models.DecimalField(_('Unitary Price'), max_digits=12, \
    decimal_places=2)

    def __unicode__(self):
        return self.description
    class Meta:
        abstract = True

class EmittedBill(BillHeader, BillBody, BillFooter):
    pass

class ReceivedBill(BillHeader, BillBody, BillFooter):
    pass

ユーザーが Emmited または Received 請求書を追加するBillHeaderと、通常のフィールドセットとして表示する必要がBillBodyありますが、 .BillFooterTabularInline

それらを admin.py に TabularInline として配置するForeignKeyと、関連するモデルに が必要であるというエラーが発生します。もちろん、これらの外部キーは下部に宣言されているため、配置できません。皆さんはこれを「後方外部キー」と呼んでいると思います。

私の質問はこれです: 管理者に TabularInlines を混乱させることなく表示するにはどうすればよいですか?. 私は抽象基本クラスなしでそれを行うことができますが、別の問題が発生します.TabularInlineに他のForeignKeyが表示されます(EmitedBillsを使用している場合は、TabularInlineでReceivedBillsへのFKが表示され、その逆も同様です)、除外できませんでした彼ら。

ばかげた質問で申し訳ありませんが、私はプログラマーではなく (単なる趣味です)、データ モデルをめちゃくちゃにしています。


私はよりよく説明します:

私は 2 種類の請求書を持ってEmittedおりReceived、どちらも管理者ホームに表示されます (そのため、BooleanFieldマークを付けるために a を使用しませんでした)。両方のタイプには、自動生成される請求書番号を除いて同じフィールドEmmittedがあります。各請求書は、番号、クライアント、日付を含む 1 つのヘッダー、説明、金額、価格などを含む 1 つ以上の本文インライン エントリ、および税抜きの合計金額、適用税などを示す 1 つのインライン フッターで構成されます。


アップデート

すべてを実行しましたが、問題があります。新しいモデルの BillBody には 2 つの FK (EmitedBill と ReceivedBill) があり、TabularInline に表示されます。どうすれば非表示にできますか?field.exclude() でエラーが発生します。

4

1 に答える 1

2

あなたの質問を完全には理解していませんが、使用できます

ForeignKey('ModelName')

それ以外の

ForeignKey(ModelName)

ModelNameモデルがまだ宣言されていない場合。多分これはあなたの問題を解決します。

インライン管理者 ( など) は、TabularInlineで作成された 1 対多の関係がある場合にのみ使用されます。そのような外部キーがない場合は、インライン管理者を使用できません。継承は a とは明らかに異なります。ForeignKeyForeignKey

ただし、データモデルが間違っていると思います。お札を収納したいらしい。emitted紙幣には、紙幣と紙幣の2種類がありますreceivedemittedと請求書 の両方receivedに同じフィールドがあります。さらに、各請求書は、番号、クライアント、日付を含むヘッダー、1 つ以上の本文エントリで構成され、各エントリには格納する情報BillBodyと 1 つ以上の小数が格納される必要がありますbase_number


あなたにとっておそらくより良いデータモデル

class Bill(models.Model):
    number = models.CharField(_('Bill number'), max_length=10, unique=True, default=__number)
    client = models.ForeignKey(ClienteYProveedor, verbose_name=_('Client'))
    date = models.DateTimeField(_('Date'), default=datetime.now)

    def get_total_price(self):
        return sum([entry.price for entry in self.entries])

class BillEntry(models.Model):
    bill = models.ForeignKey(Bill, related_name='entries')

    description = models.CharField(_('Description'), max_length=200)
    amount = models.DecimalField(_('Amount'), max_digits=6, decimal_places=2)
    discount = models.DecimalField(_('Discount'), max_digits=4, decimal_places=2)
    price = models.DecimalField(_('Price'), max_digits=12, decimal_places=2)
    unitaryprice = models.DecimalField(_('Unitary Price'), max_digits=12, decimal_places=2)

__unicode__メソッドは省きました。

BillEntryこれでtoからの外部キーが得られBill、表形式のインラインを使用できるようになりました。の使い方がよくわからなかったので省略base_importしました。

価格計算

常にorpriceのような値にする必要がある場合は、これをフィールドに入力するのではなく、必要なときに Python またはデータベースで計算する必要があります。Python でこれを行いたい場合は、 と同様の方法を使用できます。データベースにクエリを実行するときにそれらを計算したい場合、Django で動作させるのは少し難しくなります。amount*unitaryprice - discountamount*(unitaryprice-discount)get_total_price

最後のケースでは、SQL ビューを見ることができますが、これは初心者には少し難しすぎると思います。もう 1 つのオプションは、カスタム SQL 式を使用することです。

BillEntry.objects.extra(select={'price': 'amount*unitaryprice-discount'})

これにより、選択中にすべてのエントリの価格が計算されます。

アップデート

発行された請求書と受け取った請求書に 2 つのサブクラスを追加し、複数テーブルの継承を使用すると、1 つの外部キーを からBillEntryに使用できますBill

class EmittedBill(Bill):
    pass

class ReceivedBill(Bill):
    pass

おそらく、Django によって生成されるデータベース モデルについても考える必要があります。通常、データベースには基本データのみを保存し、計算されたデータは保存したくありません (フッターで行いたい場合など)。unitarypriceしたがって、価格が何らかの数式やなどを使用して計算される場合amount、この数式の結果を保存するのではなく、必要に応じて再計算する必要があります (最終的には再計算を避けるためにキャッシュします)。これを行わないと、ある時点で何か (たとえばamount) を更新し、計算された値 ( price) を更新するのを忘れて、データベースに矛盾が生じる可能性があります (したがって、アプリケーションにバグが発生します)。優れたデータベースには制約があるため、少なくとも 1 つの制約を破らない限り、一貫性のないデータベースを格納することはできません。

請求書ごとに個別のヘッダーとフッターが必要な理由もわかりません。モデルは実際の請求書ではなく、請求書の情報を格納します。ヘッダーとフッターを表示したい場合は、モデル自体ではなく、ビュー レイヤー (テンプレート) でこれを行う必要があります。

于 2010-06-30T14:42:40.560 に答える