2014-06-27 17 views
7

views.pyDjango ORM Zugang Benutzertabelle durch mehrere Modelle

ich queryset bin zu schaffen, möchte ich als JSON serialisiert und zurück. Die queryset sieht wie folgt aus:

all_objects = Program.objects.all() 
test_data = serializers.serialize("json", all_objects, use_natural_keys=True) 

Das alles zieht sich zurück mit Ausnahme des ‚User‘ Modell (das in zwei Modellen verknüpft ist).

models.py

from django.db import models 
from django.contrib.auth.models import User 

class Time(models.Model): 
    user = models.ForeignKey(User) 
    ... 

class CostCode(models.Model): 
    program_name = models.TextField()   
    ... 

class Program(models.Model): 
    time = models.ForeignKey(Time) 
    program_select = models.ForeignKey(CostCode) 
    ... 

Frage

Meine Daten zurückgegeben hat Zeit, Programm, und CostCode Informationen, aber ich bin nicht in der Lage, die 'User' Tabelle abzufragen zurück. Wie kann ich den 'Benutzernamen' (aus der Benutzertabelle) im selben Abfrage-Set zurückgeben?

Hinweis: Ich habe meine Abfrage in all_objects = Time.objects.all() geändert, und dies ruft Benutzerinformationen ab, aber dann wird 'CostCode' nicht übernommen. Meine Modelle haben auch ModelManager, die die get_by_natural_key zurückgeben, so dass die relevanten Felder in meinem JSON erscheinen.

Letztendlich möchte ich, dass Daten aus allen vier Modellen in meinen serialisierten JSON-Feldern angezeigt werden. Ich vermisse nur den Benutzernamen.

Hier ist ein Bild davon, wie das JSON-Objekt erscheint derzeit in Firebug: Firefox's Firebug showing the JSON object

Vielen Dank für jede Hilfe!

Antwort

2

Es scheint ein bisschen Schwergewicht auf den ersten Blick, aber Sie mit Django REST-Framework aussehen könnte:
http://www.django-rest-framework.org/api-guide/serializers#modelserializer

Sie können die Serializer Klassen definieren und verwenden, ohne dass irgendetwas anderes zu tun mit dem Rahmen. Der Serializer gibt ein Python-Diktat zurück, das dann einfach in JSON ausgegeben werden kann.

Um alle Felder aus jedem verwandten Modell als verschachtelte dicts erhalten Sie tun können:

class ProgramSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = Program 
     depth = 2 

all_objects = Program.objects.all() 
serializer = ProgramSerializer(all_objects, many=True) 
json_str = json.dumps(serializer.data) 

anzupassen, welche Felder für jedes Modell enthalten sind Sie eine ModelSerializer Klasse für jede Ihrer Modelle definieren müssen, für

class UserSerializer(serializers.ModelSerializer): 
    class Meta: 
     model = User 
     fields = ('username',) 

class TimeSerializer(serializers.ModelSerializer): 
    """ 
    specifying the field here rather than relying on `depth` to automatically 
    render nested relations allows us to specify a custom serializer class 
    """ 
    user = UserSerializer() 

    class Meta: 
     model = Time 

class ProgramSerializer(serializers.ModelSerializer): 
    time = TimeSerializer() 

    class Meta: 
     model = Program 
     depth = 1 # render nested CostCode with default output 

all_objects = Program.objects.all() 
serializer = ProgramSerializer(all_objects, many=True) 
json_str = json.dumps(serializer.data) 
+0

Danke! Ich habe das getestet und einfach bestätigt, dass es funktioniert hat. – Will

2

Was Sie wirklich wollen, ist eine "tiefe" Serialisierung von Objekten, die Django nicht nativ unterstützt. Dies ist ein häufiges Problem und wird hier im Detail diskutiert: Serializing Foreign Key objects in Django. Siehe diese Frage für einige Alternativen.

Normalerweise erwartet Django, dass Sie die Objekte Time, CostCode, Program und User separat serialisieren (d. H. Für jedes ein separates JSON-Array) und diese durch IDs referenzieren. Die IDs können entweder die numerischen Primärschlüssel (PK) oder ein mit natural_key definierter "natürlicher" Schlüssel sein.

Sie können natural_key verwenden, um alle gewünschten Felder zurückzugeben, einschließlich user.username. Alternativ könnten Sie eine benutzerdefinierte Serializer-Ausgabe definieren, was auch immer Sie dort haben wollen. Einer dieser Ansätze wird es wahrscheinlich unmöglich machen, die Daten zurück in eine Django-Datenbank zu laden, was für Sie kein Problem darstellt.

+0

Dank antonm: nur die username für die time.user Beispiel ausgegeben wird. Ich habe tatsächlich diesen Thread durchgesehen, konnte aber keine aktuelle Lösung finden (der Serializer Wad of Stuff unterstützt Django 1.6 nicht). Wenn ich am Ende der Woche keine bessere Antwort habe, akzeptiere ich deine am besten. – Will