django - adding a counter for every ManyToMany field added

69 views
Skip to first unread message

luke lukes

unread,
Nov 13, 2012, 3:49:03 PM11/13/12
to django...@googlegroups.com
Hi everyone. hi have these models:

      #models.py

class Subject(models.Model):
name = models.CharField("Name",max_length=50, blank=True)
...
...

class Activity(models.Model):
label = models.CharField("Act. name",max_length=150)
price = models.DecimalField("price", max_digits=10, decimal_places=2,default=0)
count = models.IntegerField("Count", default=0)

def __unicode__(self):
   return u"%s" % (self.label)
class Meta:
   verbose_name_plural = "Activities"


class Invoice(models.Model):
subject = models.ForeignKey(Subject)
date = models.DateField(default=date.today())
activities = models.ManyToManyField(Activity)
....
....


while creating a new Invoice instance on admin, i can select the many to many fields 'activities', but i'd like to have an additional counter (eg. an IntegerField) as an Invoice field to count and save the quantity of each activity added to my Invoice instance. Is this possible?

I mean: for each 'Activity' added to an Invoice instance, i need to count the amount of that activity.


thanks,

LuKe


Nikolas Stevenson-Molnar

unread,
Nov 13, 2012, 5:24:40 PM11/13/12
to django...@googlegroups.com
With an Invoice instance, you can easily get the number of related Activity objects:

i = Invoice.objects.get(pk=1)
num_activities = i.activities.all().count()

_Nik
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/F07dICRAF9kJ.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Message has been deleted

luke lukes

unread,
Nov 13, 2012, 6:09:24 PM11/13/12
to django...@googlegroups.com
Hi. I don't need a total counter for all related activities. I need a counter for each related Activity:
Invoice instance:
            activity A -> counter: 3
            activity B -> counter: 5
            ...
            ...

is this possible?
thanks,
Luke

Nikolas Stevenson-Molnar

unread,
Nov 13, 2012, 6:35:44 PM11/13/12
to django...@googlegroups.com
I'm not sure I understand. Do you want the value of the "count" field in the Activity model? In that case, you could use values:

activity_counts = i.activities.all().values('id', 'count') #Will give you something like [{'id': 1, 'count': 3}, {'id': 2, 'count': 5}, ...]

_Nik
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/S94XcwpnGkUJ.

Vibhu Rishi

unread,
Nov 13, 2012, 11:44:52 PM11/13/12
to django...@googlegroups.com
Would this not work : 

count = i.objects.filter(activities=Activity).count()

Where you would put the count in a for loop for the Activity and iterate over it. 

V.
Simplicity is the ultimate sophistication. - Leonardo da Vinci
Life is really simple, but we insist on making it complicated. - Confucius

Bill Freeman

unread,
Nov 14, 2012, 11:27:22 AM11/14/12
to django...@googlegroups.com
Clearly you could do this with raw SQL.  But you might find a way to do an aggregation to get it, see
    https://docs.djangoproject.com/en/1.4/topics/db/aggregation/
 
Bill

Tom Evans

unread,
Nov 14, 2012, 12:15:25 PM11/14/12
to django...@googlegroups.com
Perhaps I'm missing something, everyone else is rattling on about
aggregating and counting, but this is about invoicing for the right
number of activities, right?

That is a classical invoice scenario. With each item ('Activity')
added to the invoice, you need to record the number of those items
added so that you can calculate the value of that line in the invoice.
This is done by adding additional information to the join table, which
in django is done by adding a 'through' model to model the ManyToMany
link.

https://docs.djangoproject.com/en/1.4/topics/db/models/#intermediary-manytomany

Typically, when dealing with invoices, this model would be called a
LineItem. I would model it like so:

class Invoice(Model):
activities = ManyToManyField('Invoice', through='LineItem')


class Activity(Model):
price = DecimalField(decimal_places=2)


class LineItem(Model):
per_item_price = DecimalField(decimal_places=2)
num_items = PositiveIntegerField(default=1)
invoice = ForeignKey('Invoice')
activity = ForeignKey('Activity')

Copying the item price to the LineItem when you create it allows your
invoice to remain the same total even if you change the price of the
activity (which is a plus in any financial system, once an invoice is
created, clients expect them to remain the same total!).

Cheers

Tom
Reply all
Reply to author
Forward
0 new messages