2009-11-27 6 views
2

я не знаю, если это лучший способ решить мою проблему, если нет, скажите мне плз :)Джанго - Добавить онлайн столбцы «выберите»

У меня есть эта модель:


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) 

Теперь я хочу, чтобы получить одну информацию о пользователе, но я хочу добавить 3 новых «столбцы» онлайн:

всего = платина + золото + серебро + бронза

точка = платина * 100 + золото * 50 + серебро * 25 + бронза * 10

и сортировать по «точке», после сортировки, поставить новый столбец с порядковым номером: rank (1-n).

Могу ли я это сделать (или часть этого) работать только с моделью?

ответ

3

Уверен, что существует множество способов достижения такого поведения. Тот, о котором я сейчас думаю, - это поля Custom Model Manager и переходные модели.

Ваш класс может выглядеть так:

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'] 

Таким образом, вы можете использовать следующую команду и получить общее и точка рассчитывается:

user_trophies = userTrophy.objects.all() 

for user_trophy in user_trophies: 
    print user_trophy.total 
+0

Что такое "переходные поля модели"? –

+1

В целом в модели есть два типа полей. Постоянные поля и переходные поля. Постоянные поля представлены полями данных, тогда как переходные поля живут так долго, как только объект живет. Это означает, что временные поля временно. Это не «термин джанго». Это более общий термин для такого рода полей. – Jens

+0

В вашем примере общее число и точки являются атрибутами класса. Является ли метаклас Django чем-то особенным с ними, чтобы превратить их в атрибуты уровня экземпляра? –

1

Это больше Последующие вопрос, чем ответ, но возможно ли сделать что-то вроде:

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

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

затем вызовите что-то вроде объекта.points в шаблон. Мне просто интересно, если это возможно.

+0

Конечно, возможно, модели Django - это просто классы Python, и вы можете определить любые методы, которые вам нравятся на них. –

+0

Недостатком такого метода является то, что ORM не может использовать его в запросах. –

3

Вот как я это сделаю. Добавить столбцы «общий» и «точки» для вашей модели, как это:

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

переопределять метод сохранения для вашей модели:

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) 

С общими и точками как граждане первого класса на вашу модели , ваша концепция «ранга» становится вопросом упорядочивания и разрезания объектов UserTrophy.

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

Вы также хотите, чтобы ваши поля были проиндексированы, поэтому ваши запросы эффективны.

Если вам не нравится идея размещения этих полей в вашей модели, вы можете использовать функцию объектов заданий Django extra, чтобы вычислить ваше общее количество и очки на лету. Я не использую это очень часто, поэтому, возможно, кто-то еще может собрать пример.

Кроме того, я рекомендую вам прочитать PEP 8 для соглашений о кодировании Python.

+0

Похож на хороший способ сделать это! Может быть, это лучший способ, поскольку вы делаете это только при вычислении значений один раз, а не каждый раз, когда вы загружаете объект! – Jens

+0

Единственным недостатком является то, что если вы обновите таблицу за пределами ORM Django, вам придется помнить, что ваши очки и общее обновление также должны быть сохранены. –

+0

благодарит за ответ! просто вопрос, зачем мне читать PEP 8? Я делаю ошибку стиля в своем коде? – fabriciols

Смежные вопросы