0

I got a model containing two counters :

    class MyObject(models.Model):
        ...
        student_c = models.PositiveIntegerField(default=0, blank=True, null=True)
        company_c = models.PositiveIntegerField(default=0, blank=True, null=True)

    def total_followers(self):
        return self.student_c + self.company_c

one is working perfectly and returns an integer value but the other one returns :

django.db.models.expressions.ExpressionNode object at 0x7ff4d8320a10

I tried to change PositiveIntegerField to IntegerField and to rename the field with another name but I still get the same result ? I destroyed the database and rebuilt it many times

In my template I can see this : (+: (DEFAULT: ), 1)

In fact I'm trying to do an atomic increment like this:

project = get_object_or_404(Project, pk=kwargs['pk'])
project.student_c = F('student_c') + 1
project.save(update_fields=['student_c']) or even just project.save()

This is where the problem is coming from. I looked there and I found the same code : Atomic increment of a counter in django

What am I doing wrong ?

Any help would be very appreciated.

Thanks

Community
  • 1
  • 1
samidarko
  • 590
  • 7
  • 20
  • What is the code that returns an ExpressionNode? – jproffitt Sep 16 '13 at 23:31
  • I put a debugg trace in my "total_followers" method and when I call "self.company_c" I got an integer but "self.student_c" returns an ExpressionNode object (I checked my sql schema both fields are identical) – samidarko Sep 17 '13 at 08:50

2 Answers2

0

I don't know if this is similar to your problem, but maybe can help you

http://www.voidspace.org.uk/python/weblog/arch_d7_2011_04_30.shtml

Maybe you need to call .save before call total_followers in your view...

For example:

import model.MyObject

myObj = MyObject.objects.create(....)
myObj.save()

myObj.total_followers()
Romans 8.38-39
  • 456
  • 4
  • 14
0

I'm not sure you're using the F() object correctly. Have you tried just doing

Projects.objects.filter(pk=kwargs['pk']).update(student_c=F('student_c') + 1)

That would replace those three lines. Also you could try this for the second line:

project.student_c = project.student_c + 1
jproffitt
  • 6,225
  • 30
  • 42
  • I know the first one is working fine but this is making another query when I previously get my object in my view with get_object_or_404 instruction. I don't understant why it's not possible to just make an atomic increment on my "project" variable. In fact I'm looking for an elegant solution to query my object and raise 404 if not found then doing an atomic increment on it. Your second suggestion is not atomic increment (I actually use it) ? In fact you probably right and what I want is maybe just not possible my way ? – samidarko Sep 17 '13 at 12:24
  • Is it updating the database correctly? Is the problem that after you run the code, `project.student_c` is an `ExpressionNode`? You might have to re-query the database to get the updated counter. Or you could do my second suggestion and wrap it in a transaction. – jproffitt Sep 17 '13 at 12:32
  • I choose the first one, I think that's the best way for me. Thanks again for you help. – samidarko Sep 17 '13 at 14:10