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:
try:
initial['value'] is None
except KeyError:
initial['currency'] = a
initial['amount'] = amount[a]
print(initial)
return initial
def post(self, request, *args, **kwargs):
print("post()")
req = request.POST.copy()
req.pop('csrfmiddlewaretoken')
self.jobs = Job.objects.filter(id__in=req.keys(),
client_id=kwargs['client_id'])
return super(CreateView, self).post(request,*args,**kwargs)
# standard_form.html
{% extends 'main_form.html' %}
{% block formaction %}{{ formaction }}{% endblock %}
{% block 'title' %}{{ title }}{% endblock %}
{% block form %}
{% for field in form %}
<div class="field{% if field.is_required %} required{% endif %}">
<div class="form-error">{{ field.errors }}</div>
{{ field.label_tag }}
{{ field }}
</div>
{% endfor %}
{% endblock %}
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/
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/3daa6fd9-be1a-4b15-886c-454aa7ed86f4%40googlegroups.com.
To post to this group, send email to djang...@googlegroups.com.
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?
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/9804ee28-d865-4878-bd3f-1f46d82c5a1e%40googlegroups.com.