2010-06-04 9 views
1

Donc, fondamentalement, j'ai un assez grand projet Django. C'est un portail web privé qui permet aux utilisateurs de gérer différentes tâches liées au téléphone.Django peut-il trier automatiquement les champs de modèle?

Plusieurs pages du portail fournissent une liste d'objets Modèle aux utilisateurs et répertorient tous leurs attributs dans un tableau HTML (afin que les utilisateurs puissent visualiser visuellement une liste de ces éléments). Le problème que je rencontre est: Je ne trouve pas de méthode Django-ish ou pythonique pour gérer le tri de ces objets Modèle par nom de champ. À titre d'exemple de ce dont je parle, voici une de mes vues qui répertorie tous Partyline objets Modèle:

def list_partylines(request): 
    """ 
    List all `Partyline`s that we own. 
    """ 

    # Figure out which sort term to use. 
    sort_field = request.REQUEST.get('sortby', 'did').strip() 
    if sort_field.startswith('-'): 
     search = sort_field[1:] 
     sort_toggle = '' 
    else: 
     search = sort_field 
     sort_toggle = '-' 

    # Check to see if the sort term is valid. 
    if not (search in Partyline._meta.get_all_field_names()): 
     sort_field = 'did' 

    if is_user_type(request.user, ['admin']): 
     partylines = Partyline.objects.all().order_by(sort_field) 
    else: 
     partylines = get_my_partylines(request.user, sort_field) 

    variables = RequestContext(request, { 
     'partylines': partylines, 
     'sort_toggle': sort_toggle 
    }) 
    return render_to_response('portal/partylines/list.html', variables) 

Le code de tri permet essentiellement aux utilisateurs de spécifier une/url/sortby = paramètre model_field_name qui le fera? puis renvoyez une liste triée d'objets chaque fois que les utilisateurs cliquent sur le nom de la table HTML affiché sur la page. Étant donné que j'ai diverses vues dans diverses applications qui affichent toutes une liste d'objets Modèle, et nécessitent un tri, je me demande s'il existe une façon générique de faire ce tri pour que je ne sois pas obligé de le faire? Je suis désolé si cette question est un peu floue, j'ai du mal à trouver la bonne façon d'exprimer cette question.

Merci.

Répondre

2

La façon dont je verrais faire ceci est à travers un QuerySet personnalisé. Dans votre modèle, vous pouvez définir la classe QuerySet et y ajouter votre tri. Afin de maintenir toute la logique dans l'objet de modèle, je déplacerais également le contenu de get_my_partylines dans le QuerySet, aussi.

## This class is used to replicate QuerySet methods into a manager. 
## This way: Partyline.objects.for_user(foo) works the same as 
## Partyline.objects.filter(date=today).for_user(foo) 
class CustomQuerySetManager(models.Manager): 
    def get_query_set(self): 
     return self.model.QuerySet(self.model) 
    def __getattr__(self, attr, *args): 
     try: 
      return getattr(self.__class__, attr, *args) 
     except AttributeError: 
      return getattr(self.get_query_set(), attr, *args) 


class Partyline(models.Model): 
    ## Define fields, blah blah. 
    objects = CustomQuerySetManager() 
    class QuerySet(QuerySet): 
     def sort_for_request(self, request): 
      sort_field = request.REQUEST.get('sortby', 'did').strip() 
      reverse_order = False 
      if sort_field.startswith('-'): 
       search = sort_field[1:] 
      else: 
       search = sort_field 
       reverse_order = True 

      # Check to see if the sort term is valid. 
      if not (search in Partyline._meta.get_all_field_names()): 
       sort_field = 'did' 

      partylines = self.all().order_by(sort_field) 
      if reverse_order: 
       partylines.reverse() 
      return partylines 
     def for_user(self, user): 
      if is_user_type(request.user, ['admin']): 
       return self.all() 
      else: 
       ## Code from get_my_partylines goes here. 
       return self.all() ## Temporary. 

views.py:

def list_partylines(request): 
    """ 
    List all `Partyline`s that we own. 
    """ 
    partylines = Partylines.objects.for_user(request.user).sort_for_request(request) 
+0

J'aime l'approche for_user. Est-ce que c'est en quelque sorte une convention ou simplement du bon sens? – Agos

+0

Juste quelque chose que j'ai piraté ensemble (avec l'aide de SO) comme une convention pour mes propres projets. Cela semble logique et garde le code lisible. –

0

Voici un bon exemple de comment cela est fait de façon générique dans django.contrib.admin.views.main.ChangeList bien que cela ne se limite pas au tri, vous pouvez parcourir son code pour trouver quelques astuces et idées. Vous pouvez également regarder django.contrib.admin.options.ModelAdmin la méthode changelist en particulier pour obtenir plus de contexte.

Questions connexes