2014-06-27 10 views
7

views.pyDjango ORM stół dostępu użytkownika przez wielu modeli

Tworzę queryset który chcę serializacji i powrócić jako JSON. Queryset wygląda następująco:

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

ten cofa się wszystko z wyjątkiem modelu „User” (która jest połączona na dwóch modelach).

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) 
    ... 

Pytanie

My powrócił danych ma czas, program i informacje CostCode, ale jestem w stanie do kwerendy z powrotem do stołu 'user'. Jak mogę odzyskać nazwę "użytkownika" (z tabeli użytkownika) w tym samym zapytaniu?

Uwaga: Zmieniono mój zestaw zapytań na all_objects = Time.objects.all(), co powoduje pobranie informacji o użytkowniku, ale nie powoduje pobrania "kodu kosztu". Moje modele mają również ModelManagers, które zwracają get_by_natural_key, więc odpowiednie pola pojawiają się w moim JSON.

Ostatecznie chcę, aby dane ze wszystkich czterech modeli pojawiały się w moich zserializowanych polach JSON, po prostu brakuje mi "nazwy użytkownika".

Oto obraz jak obiekt JSON obecnie pojawia się w Firebug: Firefox's Firebug showing the JSON object

Dzięki za wszelką pomoc!

Odpowiedz

2

Wydaje wagi ciężkiej bitowego na pierwszy rzut oka, ale można spojrzeć na odpoczynek przy użyciu Django Framework:
http://www.django-rest-framework.org/api-guide/serializers#modelserializer

Można zdefiniować i używać klas serializer bez konieczności robić niczego innego z ramami. Serializator zwraca ducha Pythona, który można łatwo zrzucić na JSON.

Aby uzyskać wszystkie pola z każdego powiązanego modelu jako zagnieżdżone dicts można zrobić:

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) 

aby dostosować które pola są dostępne dla każdego modelu trzeba będzie zdefiniować klasę ModelSerializer dla każdego z modeli, dla przykładem na wyjście tylko dla time.userusername:

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

Dzięki! Przetestowałem to i po prostu zweryfikowałem, że zadziałało. – Will

2

To, czego naprawdę chcesz, to "głęboka" serializacja obiektów, których Django natywnie nie obsługuje. Jest to częsty problem, który omówiono szczegółowo tutaj: Serializing Foreign Key objects in Django. Zobacz to pytanie dla niektórych alternatyw.

Zwykle Django oczekuje serializacji osobno obiektów Czasu, Kosztów, Programów i Użytkowników (tj. Oddzielnej tablicy JSON dla każdego z nich) i odnoszenia się do nich za pomocą identyfikatorów. Identyfikatory mogą być numerycznymi kluczami głównymi (PK) lub kluczem "naturalnym" zdefiniowanym przez natural_key.

Możesz użyć numeru natural_key, aby zwrócić wszystkie wymagane pola, w tym user.username. Alternatywnie możesz zdefiniować niestandardowe wyjście serializera, tam gdzie chcesz. Każde z tych podejść prawdopodobnie uniemożliwi załadowanie danych z powrotem do bazy danych Django, co może nie być dla ciebie problemem.

+0

Dzięki antonm. Przeszukałem ten wątek, ale nie mogłem znaleźć aktualnego rozwiązania (serializator Wad of Stuff nie obsługuje Django 1.6). Jeśli nie otrzymam lepszej odpowiedzi przed końcem tygodnia, przyjmuję twoje jako najlepsze. – Will

Powiązane problemy