Domanda

vedi Let se riesco a spiegarmi, ho questo modelli:

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

Quando l'utente aggiunge un disegno di legge Emmited o ricevuto ho bisogno di mostrare BillHeader come un fieldset normale, ma BillBody e hanno bisogno di essere BillFooter TabularInline.

Se metto quelli come TabularInline in admin.py, un errore aumenti dicendo che hanno bisogno di un ForeignKey ai relativi modelli. Naturalmente, non posso mettere quelle chiavi esterne, perché sono dichiarate in fondo. Penso che voi ragazzi chiamano "chiavi all'indietro stranieri".

La mia domanda è questa: come posso fare questo per mostrare TabularInlines in Admin senza fare danni ?. Posso farlo senza classi base astratte, ma poi un altro problema arriva, si vede l'altro ForeignKey nel TabularInline (se siete su EmmitedBills mostra il FK al ReceivedBills nella TabularInline e viceversa) e non ho potuto essere in grado di escludere loro.

Scusate se questa è una domanda stupida, ma io non sono un programmatore (è solo un hobby) e sto davvero facendo io un pasticcio con modelli di dati.


ti spiego meglio:

Ho due tipi di bollette, Emitted e Received e ciascuno di essi mostra sulla casa di amministrazione (è per questo che non ho usato un BooleanField per segnare loro). Entrambi i tipi hanno gli stessi campi tranne uno, il numero disegno di legge, che a sua Emmitted saranno generati automaticamente. Ogni disegno di legge è costituito il 1 ° di intestazione con il numero, il cliente e la data, 1 o più voci del corpo in linea con una descrizione, quantità, prezzo, ecc e 1 piè di pagina in linea, che mostra il prezzo totale, senza tasse, le imposte applicate, ecc.


Aggiorna

Ho fatto di tutto, ma ho un problema, nel mio nuovo modello BillBody ha due FK di (EmmitedBill e ReceivedBill) e mostrano nella TabularInline. Come posso nascondere? Field.exclude () dà un errore.

È stato utile?

Soluzione

Non capisco pienamente alla tua domanda, ma è possibile utilizzare

ForeignKey('ModelName')

anziché

ForeignKey(ModelName)

Se il modello ModelName non è già dichiarata. Forse questo risolve il problema.

In Linea amministratori (come TabularInline) vengono utilizzati solo quando si ha una relazione uno-a-molti, che viene creato da un ForeignKey sul molti lato. Se non si dispone di una chiave come straniero, quindi non è possibile utilizzare un amministratore di linea. L'ereditarietà è decisamente diverso da un ForeignKey.

Tuttavia, credo che il vostro modello di dati è sbagliato. Sembra che si vuole memorizzare le bollette. Ci sono due tipi di bollette, emitted e bollette received. Entrambi i progetti emitted e received hanno gli stessi campi. Inoltre, si desidera che ogni disegno di legge è costituito da un'intestazione con il numero, il cliente e la data, 1 o più voci del corpo, in cui ogni voce memorizza le informazioni di memorizzare in BillBody e 1 o più decimali base_number.


Una probabilmente migliore modello di dati per voi

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)

ho lasciato fuori i metodi __unicode__.

Ora avete una chiave esterna da BillEntry a Bill ed è possibile utilizzare una linea tabellare. Non ho capito che l'uso di base_import così ho lasciato questo fuori.

Prezzo calcolo

Se il price deve essere sempre uguale qualcosa come amount*unitaryprice - discount o amount*(unitaryprice-discount) allora non si dovrebbe mettere questo in un campo ma o calcolare quando è necessario, sia in Python o nel database. Se si vuole fare questo in Python è possibile utilizzare un metodo simile a get_total_price. Se si vuole calcolare quando interrogare il database, allora è un po 'più difficile da farlo funzionare con Django.

In quest'ultimo caso, è possibile dare un'occhiata a una vista SQL, ma penso che questo sia un po 'troppo difficile per un principiante. Un'altra opzione è quella di utilizzare un'espressione SQL personalizzata:

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

Questo calcolerà il prezzo per tutte le voci durante la selezione.

Aggiorna

Se si aggiungono due sottoclassi per le bollette e l'uso emessi e ricevuti Multi table eredità quindi è possibile utilizzare una chiave esterna da BillEntry a Bill.

class EmittedBill(Bill):
    pass

class ReceivedBill(Bill):
    pass

Probabilmente hanno anche pensare al modello di database generato da Django. Di solito, si desidera solo per memorizzare i dati elementari nel database, e non computerizzata dei dati (come si vuole fare nel vostro piè di pagina). Quindi, se i prezzi sono calcolati utilizzando una formula e utilizzando il unitaryprice, amount ecc non si deve memorizzare il risultato di questa formula, ma ricalcolare quando necessario (ed eventualmente cache per evitare una nuova calcoli). Se non si esegue questa operazione, è probabile che ad un certo momento aggiornamento qualcosa (ad esempio, la amount) e dimenticano di aggiornare i valori calcolati (l'price) che porta a incongruenze nel database (e quindi i bug nell'applicazione). Un database buon ha vincoli in modo che sia impossibile memorizzare database incoerente senza rompere almeno un vincolo.

Anche io non vedo perché si vuole un colpo di testa separata e piè di pagina per ogni fattura. Un modello non è il disegno di legge vera e propria, memorizza le informazioni per un disegno di legge. Se si vuole avere un colpo di testa visibile e piè di pagina, allora si dovrebbe fare questo nel vostro livello di visualizzazione (il modello) e non nel modello stesso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top