2009-05-28 3 views
1

Hier sind meine Modelle:Django-Frage: Wie kann ich benutzerspezifische Informationen zu einem Domänenobjekt erhalten?

class Activity(models.Model): 
    title = models.CharField(blank=False, max_length=100) 
    description = models.TextField(blank=False) 


class UserActivityWork(models.Model): 
    activity = models.ForeignKey(Activity) 
    user = models.ForeignKey(User) 
    hours_worked = models.FloatField() 
    comment = models.TextField() 

Beispieldaten wäre, eine Aktivität von „Klettern Mount Everest“ und jeder Benutzer würde die Eingabe der Lage sein, wie lange es sie nahm und einen Kommentar.

Hier ist meine Frage: Wie kann ich eine Liste aller Aktivitäten anzeigen, und wenn der Benutzer Daten für diese Aktivität eingegeben hat, zeigen Sie die relevanten Details neben der Aktivität?

Bisher habe ich in Betracht gezogen:

  • ein Wörterbuch von UserActivityWork mit einem Schlüssel der Aktivität ID und einen Wert des UserActivityWork des Benutzers zu schaffen. Das wäre in Ordnung mit ich, aber ich habe keine Ahnung, wie zu tun dies in Django Templating-System (dh wie sagt man: {{user_work [activity.id]}})
  • Erstellen eines Objekts, das würde Halten Sie sowohl die Aktivität und UserActivityWork. Ich habe das nicht getan, weil ich hoffe, dass django einen besseren Weg hat, dies zu tun.

Jeder Einblick würde sehr geschätzt werden!

Antwort

1

Angenommen, Sie haben 2 querysets aus Ihrer Vorlage zugreifbar (sagen, wie Aktivitäten und user_activities)

Eine naive Art und Weise über jede Aktivität zu durchlaufen würde und dann über jede Benutzeraktivität.

{% for activity in activities %} 
    {{ activity.title }} 
    {% for user_activity in user_activities %} 
     {% ifequal user_activity.activity activity %} 
      Display userdata 
     {% endifequal %}  
    {% endfor %} 
{% endfor %} 

Wörterbuch Lookups kann mit einem Punkt in Vorlagen durchgeführt wird

Technisch, wenn das Template-System einen Punkt trifft, versucht es die folgenden Abfragen, die in dieser Reihenfolge (.):

  • Wörterbuch Lookup
  • Attribut Lookup
  • Methodenaufruf
  • List-Indexsuche

Eine weitere Möglichkeit, ein custom template tag zu schaffen wäre. Sie können die Aktivitätsliste wie zuvor durchlaufen und dann die Aktivität und entweder die Liste "user_activity" oder den Benutzer an das Tag übergeben, um die Suche durchzuführen und die erforderlichen Daten zu rendern.

0

Danke für den Hinweis, Gerry. Ich fand, dass das Schreiben eines benutzerdefinierten Vorlagen-Tags, wie Sie es vorgeschlagen haben, der richtige Weg war. Hier sind die blutigen Details, falls jemand darüber stolpert.

Nach Ansicht Verfahren veröffentlichte ich ein Wörterbuch „user_activity_status“, die für die in Arbeit Dies ist

diese Tätigkeit des Benutzers protokolliert einen Schlüssel von activity.id und den Wert der UserActivityWork Objekt enthält die der entsprechende Abschnitt der Vorlage.Im Grunde ist dies geht eine Variable „map_value“ mit einem Wert von

getattr(user_activity_status[activity.id], "comment") 

hinzufügen Hier ist die Vorlage:

{% load *file-name-of-the-templatetag-file* %} 
{% access_map_method user_activity_status activity.id comment %} 
{% if map_value %} 
    {{ map_value }} 
{% else %} 
    get working sucka! 
{% endif %} 

hier ist der Abschnitt der TemplateTag-Datei (siehe Gerry-Links für die Details, wie zum stellen Sie diese auf)

from django import template 

register = template.Library() 

@register.tag(name="access_map_method") 
def do_access_map_method(parser, token): 
    try:  
     tag_name, dict_name , key_name, method_name = token.contents.split() 
    except ValueError: 
     msg = '%r tag requires three arguments' % token.contents[0] 
     raise template.TemplateSyntaxError(msg) 

    return MapNode(dict_name , key_name, method_name) 

class MapNode(template.Node): 
    def __init__(self, dict_name, key_name, method_name): 
     self.dict_var = template.Variable(dict_name) 
     self.key_var = template.Variable(key_name) 
     self.method_name = method_name 

    def render(self, context): 
     try: 
      dict_obj = self.dict_var.resolve(context) 
      key_obj = self.key_var.resolve(context) 
      if key_obj in dict_obj.keys(): 
       if self.method_name: 
        context['map_value'] = getattr(dict_obj[key_obj], self.method_name) 
       else: 
        context['map_value'] = dict_obj[key_obj] 
      else: 
       context['map_value'] = '' 
     except template.VariableDoesNotExist: 
      context['map_value'] = '' 

     return '' 
Verwandte Themen