Re: what if I need to use two objects to get a third object in my templates?

2010-02-21 Thread Jeremy Dillworth
On Feb 21, 11:14 am, Jeremy Dillworth  wrote:
> and a view named list:
>
> def list(request):
>     people = Person.objects.all()
>     for p in people:
>         p.columns = [None, None, None]
>         for c in DataPoint.objects.filter(person=p, value__gt=4):
>             p.columns.append(c)
>
>     return render_to_response('people/listing.html',
> dict(people=people))

I should probably mention too that the view code in my example may be
a bit unwise. I just wanted to keep it simple. For real production
code, I would wonder if doing a query in a loop like that would scale.
Potentially this view could do dozens of queries during a single HTTP
request. A better option would be to do one hit on the DataPoint table
that pulls all the DataPoints for all the Person objects, then use
some dictionaries and lists to get them into their proper places. Or
you could even just do select_related on the DataPoints and get the
Person objects at the same time...

Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.



Re: what if I need to use two objects to get a third object in my templates?

2010-02-21 Thread Jeremy Dillworth
You could also put a columns property onto each person object.

Given the models:

class Person(models.Model):
name = models.CharField(max_length=30)

class DataPoint(models.Model):
person = models.ForeignKey(Person)
value = models.IntegerField()

and a view named list:

def list(request):
people = Person.objects.all()
for p in people:
p.columns = [None, None, None]
for c in DataPoint.objects.filter(person=p, value__gt=4):
p.columns.append(c)

return render_to_response('people/listing.html',
dict(people=people))

(the columns property above is a bit contrived, I think given your
situation--needing a certain number of columns--you'd need some logic
to put None into columns whose DB value was greater than what you
wanted, that way each person's columns property has the same number of
elements and things will line up)

You could then have a pretty simple view:



{% for person in people %}

{{ person.name }}
{% for col in person.columns %}
{% if col %}
{{ col.value }}
{% else %}
(blank)
{% endif %}
{% endfor %}

{% endfor %}




-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.



Re: Model for debt, credit and balance

2010-02-19 Thread Jeremy Dillworth
Presumably you'll eventually have enough transactions that you'll want
to start paging them. At that point, it would change how you would
arrive at the balance. If a user is looking at page 30, you shouldn't
need to retrieve the transactions from pages 1-29.

Eventually, you may want to consider something like this:

from django.db.models import Sum
PER_PAGE = 20
...
page = request.GET.get('page') or 1
start = (page - 1) * PER_PAGE
end = start + PER_PAGE

trans = Transaction.objects.order_by('date', 'id')[start:end]

earliest = trans[0]
qs = Transaction.objects.filter(date__lte=earliest.date,
id__lt=earliest.id)
previous = qs.aggregate(debit=Sum('debit'), credit=Sum('credit'))

balance = previous['debit']
balance -= previous['credit']

transaction_list = []
for tran in trans:
balance = balance + tran.debit
balance = balance - tran.credit
transaction_list.append({'transaction':tran,'balance':balance})


--Jeremy

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.



Re: Python-specific question: variable scope

2007-03-30 Thread Jeremy Dillworth


Here's a few ideas:

Solution 1 - use the __main__ module

The downside to this is that it always reads x from the "top-level"
module, in other words, the script that is being run.  So when you run
a1, you'll get "a1" when you run a2 module b will then find "a2".

a1.py
--
import b
x = "a1"
b.test()
--

a2.py
--
import b
x = "a2"
b.test()
--


b.py
--
import __main__
def test():
print __main__.x
--

I'm not sure why you're trying to do this, but it looks like having b
reference variable x which is implied to have been defined elsewhere
could cause trouble for you later.  x is sort of like a parameter to
make b work differently, so you should probably explicitly pass it to
functions in b or use x to initialize an object of a class from b.

Idea 2 - use a class to encapsulate x

If you wrap up all the functionality you need in a class inside b, you
could then pass x to the constructor and all the subsequent method
calls would have access to x.

a1.py
--
import b
x = "a1"
my_b = b.B(x)
my_b.test()
--

a2.py
--
import b
x = "a2"
my_b = b.B(x)
my_b.test()
--

b.py
--
class B(object):
def __init__(self, x):
self.x = x
def test(self):
print self.x
--

Solution 3 - Use the borg pattern

If you need all modules everywhere to see b with the same value of x,
you could use the borg pattern (singleton would work too, but I like
borg better).  This way the first a module that gets imported or run
will set b's value of x forever.

a1.py
--
import b
x = "a1"
my_b = b.B(x)
my_b.test()
--

a2.py
--
import b
x = "a2"
my_b = b.B(x)
my_b.test()
--

a3.py - note that this one will print "a1" twice, since module a1
initializes b before a3 can.
--
import a1
import b
x = "a3"
my_b = b.B(x)
my_b.test()
--

b.py
--
class B(object):
borg = None
def __init__(self, x):
if B.borg is None:
B.borg = {}
B.borg['x'] = x
self.__dict__ = B.borg

def test(self):
print self.x
--




--~--~-~--~~~---~--~~
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en
-~--~~~~--~~--~--~---