Re: unable to render initial data in ModelForm called through CreateView

2018-03-07 Thread furzihurzischleim
hmm.. i don't think so. the info about the jobs is meant to be gathered 
before creating the invoice. see, the app should let you register "jobs" 
with timing, client and wage information. after creating jobs you can 
select in a form "open" jobs, meaning they have not been part of an 
invoice. so you select the jobs and create the invoice, if saving the 
invoice is succesful, i create the ForeignKey relation from each job to 
point to the invoice.

... so the CreateView _is_ the right thing, right? or would you create the 
object "by hand" while processing the POST data and redirect it to an 
UpdateForm (and delete the instance if updating fails)?


Am Mittwoch, 7. März 2018 19:18:03 UTC+1 schrieb Matthew Pava:
>
> Correct, post is for POST, get is for GET.
>
> When a form is POSTed successfully, the user is redirected to another URL, 
> typically a success page or something of your choosing.
>
> So after your POST, if you are simply redirecting back to this CreateView, 
> you no longer have access to the invoice that you just created in this 
> view.  You are creating a completely new invoice using the GET method.
>
> Maybe you mean to be creating an UpdateView with this new information 
> about self.jobs?
>
>  
>
> *From:* django...@googlegroups.com  [mailto:
> django...@googlegroups.com ] *On Behalf Of *furzihurzischleim
> *Sent:* Wednesday, March 7, 2018 12:10 PM
> *To:* Django users
> *Subject:* Re: unable to render initial data in ModelForm called through 
> CreateView
>
>  
>
> thanks for the link, i was aware of that but was unable to find my error 
> (that's why i turned to irc, and then to the list)..
>
> it is true self.jobs is set from the post() method. that's because the 
> CreateView should be called if there are jobs selected in a POST-form. so 
> post() sets self.jobs which get processed (and summed to 
> initial['amount'] and initial['currency']) in get_initial(), which itself 
> is printed to console correctly. it then instantiated a form, which gets 
> the right arguments (initial dict) with the right values. but they won't 
> show up :(
>
> just for clarification: post() gets called if the request uses 
> POST-method, and get() gets called on GET-requests, right?
>
> i know this is more of a beginner issue, but i'm unable to get further in 
> my work at this point. thanks for your time and your advice!
>
>
> Am Mittwoch, 7. März 2018 18:44:40 UTC+1 schrieb Matthew Pava:
>
> Well, I see that you only set self.jobs in the post method in 
> CreateInvoice.  How are you seeing proper console output for get_initial 
> when self.jobs is not even set in the get method?  Are you sure you are 
> seeing exactly what you want to see?  Please double-check.  When presenting 
> the form for the first time, it will use the get method on CreateInvoice.  
> Since you did not override it, it will use the default implementation.  You 
> didn’t set self.jobs anywhere else but in the post method.
>
>  
>
> I also find this website helpful when dealing with class-based views:
>
>
> https://ccbv.co.uk/projects/Django/1.11/django.views.generic.edit/CreateView/
>
>  
>
>  
>
> *From:* django...@googlegroups.com [mailto:django...@googlegroups.com] *On 
> Behalf Of *furzihurzischleim
> *Sent:* Wednesday, March 7, 2018 7:11 AM
> *To:* Django users
> *Subject:* Re: unable to render initial data in ModelForm called through 
> CreateView
>
>  
>
> :)
>
> Invoice Form is "just" a normal Modelform - nothing fancy added.
>
> class InvoiceForm(forms.ModelForm):
> class Meta:
> model = Invoice
> fields = '__all__'
> def __init__(self,*args,**kwargs):
> print("InvoiceForm.__init__();;;")
> #print( self)
> print( args)
> print( kwargs)
> return super(InvoiceForm, self).__init__( *args, **kwargs )
>
> Am Dienstag, 6. März 2018 18:08:33 UTC+1 schrieb Matthew Pava:
>
> Let's see InvoiceForm. 
> Also, it doesn't make much of a different, but I wouldn't call copy on the 
> super.get_initial() method. 
>
>   
> -Original Message- 
> From: django...@googlegroups.com [mailto:django...@googlegroups.com] On 
> Behalf Of Gabriel Wicki 
> Sent: Sunday, March 4, 2018 2:48 PM 
> To: django...@googlegroups.com 
> Subject: unable to render initial data in ModelForm called through 
> CreateView 
>
> hello list 
>
> i ran into some weird stuff and neither i nor 2 gentle folks down at the 
> irc-chat could find any obvious problems. task should have been easy: 
> calcula

Re: unable to render initial data in ModelForm called through CreateView

2018-03-07 Thread furzihurzischleim
:)

Invoice Form is "just" a normal Modelform - nothing fancy added.

class InvoiceForm(forms.ModelForm):
class Meta:
model = Invoice
fields = '__all__'
def __init__(self,*args,**kwargs):
print("InvoiceForm.__init__();;;")
#print( self)
print( args)
print( kwargs)
return super(InvoiceForm, self).__init__( *args, **kwargs )

Am Dienstag, 6. März 2018 18:08:33 UTC+1 schrieb Matthew Pava:
>
> Let's see InvoiceForm. 
> Also, it doesn't make much of a different, but I wouldn't call copy on the 
> super.get_initial() method. 
>
>   
> -Original Message- 
> From: django...@googlegroups.com  [mailto:
> django...@googlegroups.com ] On Behalf Of Gabriel Wicki 
> Sent: Sunday, March 4, 2018 2:48 PM 
> To: django...@googlegroups.com  
> Subject: unable to render initial data in ModelForm called through 
> CreateView 
>
> hello list 
>
> i ran into some weird stuff and neither i nor 2 gentle folks down at the 
> irc-chat could find any obvious problems. task should have been easy: 
> calculate some special initial data and present it as initials in a form. 
> the form is showed correctly, and the right values are printed in console.. 
> and, of course, there is no error raised.. 
>
> thank you for any hints! i've been stuck here 
>
>
> gabriel 
>
>
>
>
> # models.py 
> class AmountModel(models.Model): 
> class Meta: 
> abstract = True 
> currencies = ( 
> ('CHF', "Swiss Francs"), 
> ('EUR', "Euros"), 
> ) 
> amount = models.FloatField(); 
> currency = models.CharField( max_length=3, choices=currencies, 
> default='CHF' ) 
>
> def __str__(self): 
> return "{} {}".format(self.amount, [ j[1] for i,j in 
> enumerate(self.currencies) if j[0] == self.currency][0] ) 
> def short(self): 
> return "{} {}".format([ j[0] for i,j in 
> enumerate(self.currencies) if j[0] == self.currency][0], self.amount ) 
> def __add__(self, other): 
> return AmountModel(amount=self.amount+other.amount, 
> currency=self.currency) 
>
> class DocumentModel(models.Model): 
> class Meta: 
> abstract = True 
> tex = models.FileField(verbose_name = "TeX") 
> pdf = models.FileField(verbose_name = "PDF") 
> def generate_pdf( self ): 
> return 
>
> class Invoice(AmountModel, DocumentModel): 
> STATUS = ( 
> ("o", "open"), # initialized 
> ("c", "complete"), # completed (no info missing) 
> ("s","sent"), # sent 
> ("p","pending"), # sent but money not yet received 
> ("pd","paid") # paid and archived 
> ) 
> client = models.ForeignKey( 'Client', on_delete=models.CASCADE ) 
> title = models.CharField( max_length=200 ) 
> status = models.CharField( max_length=2, choices = STATUS ) 
> number = models.IntegerField( blank=True ) 
> date_created = models.DateField( auto_now=True ) 
> date_sent = models.DateField( blank=True ) 
> date_paid = models.DateField( blank=True ) 
>
> @property 
> def jobs(self): 
> return Job.objects.filter( invoice=self ) 
>
> @property 
> def expenses(self): 
> return Expense.objects.filter( invoice=self ) 
>
> def __str__(self): 
> if self.status.startswith('p'): 
> return '%d %s'.format(self.number, self.title ) 
> return self.title 
>
> def update_status(self): 
> if (self.date_sent == None): 
> self.status = STATUS[0][0] 
> elif (self.date_paid == None): 
> self.status = STATUS[1][0] 
> else: 
> self.status = STATUS[2][0] 
> return 
>
> def calculate_amount(self): 
> amount = 0 
> for o in [ self.jobs, self.expenses ].flatten: 
> amount += o.amount 
> self.amount = amount 
> self.save() 
> return 
>
> def create_tex( self ): 
> template_file = 'templates/invoice.tex' 
> t = loader.get_template(template_file) 
> context = { 
> 'title': self.title, 
> } 
> filename = '%d %s'.format(self.number, slugify(self.title) ) 
> self.tex.file = open(filename+'.tex', 'w') 
> self.tex.file.write(smart_str( t.render(context) )) 
> return 
>
> def send_to_client( self ): 
> return 
>
> # views.py 
> class CreateInvoice(CreateView): 
> model = Invoice 
> form_class = InvoiceForm 
> template_name = 'standard_form.html' 
>
> def get_initial(self): 
> initial = super(CreateView, self).get_initial().copy() 
> initial['title'] = "blablabla" 
> amount = {'CHF': 0, 'EUR': 0} 
> currency = self.jobs[0].worth.currency 
> for j in self.jobs: 
> amount[j.worth.currency] += j.worth.amount 
> for a in amount.keys(): 
> if not amount[a] == 0: 
>