开发者

Django - Add online columns in "select"

I dont know if this is the best way to resolve my problem, if isn't , tell me plz :)

I have this model :


class userTrophy(models.Model):
 user     = models.ForeignKey(userInfo)
 platinum = models.IntegerField()
 gold    = models.IntegerField()
 silver  = models.IntegerField()
 bronze  = models.IntegerField()
 level   = models.IntegerField()
 perc_level  = models.IntegerField()
 date_update = models.DateField(default=datetime.now, blank=True)

No开发者_运维知识库w i want to retrieve one user info, but i want add 3 new "columns" online :

total = platinum + gold + silver + bronze

point = platinum * 100 + gold * 50 + silver * 25 + bronze * 10

and sort by "point", after sort, put a new column, with a sequencial number: rank (1-n).

Can i do this ( or part of this ) working only with the model ?


I am sure there are many ways to achieve this behavior. The one I am thinking of right now is a Custom Model Manager and transient model fields.

Your class could look like so:

from django.db import models
from datetime import datetime

class UserTrophyManager(models.Manager):
  def get_query_set(self):
    query_set = super(UserTrophyManager, self).get_query_set()

    for ut in query_set:
      ut.total = ut.platinum + ut.gold + ut.silver + ut.bronze
      ut.points = ut.platinum * 100 + ut.gold * 50 + ut.silver * 25 + ut.bronze * 10

    return query_set

class UserTrophy(models.Model):
  user         = models.CharField(max_length=30)
  platinum     = models.IntegerField()
  gold         = models.IntegerField()
  silver       = models.IntegerField()
  bronze       = models.IntegerField()
  level        = models.IntegerField()
  perc_level   = models.IntegerField()
  date_update  = models.DateField(default=datetime.now, blank=True)

  total        = 0
  point        = 0

  objects      = UserTrophyManager()

  class Meta:
    ordering = ['points']

So you can use the following and get total and point calculated:

user_trophies = userTrophy.objects.all()

for user_trophy in user_trophies:
    print user_trophy.total


Here's the way I would do it. Add the columns 'total' and 'points' to your model, like this:

class UserTrophy(models.Model):
    ...
    total = models.IntegerField()
    points = models.IntegerField()
    ...

Override the save method for your model:

def save(self, *args, **kwargs):
    # Compute the total and points before saving
    self.total = self.platinum + self.gold + self.silver + self.bronze
    self.points = self.platinum * 100 + self.gold * 50 + \
        self.silver * 25 + self.bronze * 10

    # Now save the object by calling the super class
    super(UserTrophy, self).save(*args, **kwargs)

With total and points as first class citizens on your model, your concept of "rank" becomes just a matter of ordering and slicing the UserTrophy objects.

top_ten = UserTrophy.objects.order_by('-points')[:10]

You'll also want to make sure you have your fields indexed, so your queries are efficient.

If you don't like the idea of putting these fields in your model, you might be able to use the extra feature of Django query set objects to compute your total and points on the fly. I don't use this very often, so maybe someone else can put together an example.

Also, I recommend for you to read PEP 8 for Python coding conventions.


This is more of a followup question than an answer, but is it possible to do something like:

class userTrophy(models.Model):
... stuff...

    def points(self):
        self.gold + self.silver + self.bronze

then call something like object.points in a template. Im just curious if that is a possibility

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜