Как я могу получить некоторые (пользовательские) пользовательские данные в моем api.py? - PullRequest
1 голос
/ 29 июня 2019

Я не уверен, как передать данные из двух «вложенных» моделей в конечную точку.

Я хочу настроить некоторые данные, относящиеся к пользователю, в моем приложении Django. После некоторого поиска в Google я нашел лучший способ «расширить» пользовательскую модель по умолчанию - создать другую модель с OneToOneField, указывающим на пользователя. Вот как выглядит модель:

# models.py

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

class UserData(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    currency = models.CharField(max_length=10, default="USD")
    budget = models.IntegerField(default=500)
    showCategories = models.BooleanField(default=True)
    showLocations = models.BooleanField(default=True)
    showSources = models.BooleanField(default=True)

    def __str__(self):
        return self.user

После написания модели я написал для нее новый сериализатор:

# serializers.py

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

class UserDataSerializer(serializers.ModelSerializer):
    user = UserSerializer()

    class Meta:
        model = UserData
        fields = ('currency', 'budget', 'showCategories', 'showLocations', 'showSources', 'user')

Пока все хорошо (надеюсь).

Наконец, я изменил свой UserAPI, чтобы иметь serializer_class из UserDataSerializer. Вот как это выглядит сейчас:

# api.py

class UserAPI(generics.RetrieveAPIView):
    permission_classes = [
        permissions.IsAuthenticated,
    ]

    serializer_class = UserDataSerializer

    def get_object(self):
        # I suppose I need to return something else here but I'm not sure what.
        return self.request

При доступе к моей конечной точке я получаю следующие данные:

{
  "user": {
    "id": 1,
    "email":"email@email.com",
    "username":"myusername" 
  }
}

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


{
  "user": {
    "id": 1,
    "email": "email@email.com",
    "username": "myusername"
  },
  "currency": "USD",
  "budget": 500,
  "showCategories": true,
  "showLocations": true,
  "showSources": true
}

Изменить:

Вот так выглядит мой urls.py:

from django.urls import path, include
from .api import RegisterAPI, LoginAPI, UserAPI
from knox import views as knox_views
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView

urlpatterns = [
    path('api/auth/', include('knox.urls')),
    path('api/auth/user', UserAPI.as_view()),
    path('api/auth/register', RegisterAPI.as_view()),
    path('api/auth/login', LoginAPI.as_view()),
    path('api/auth/logout', knox_views.LogoutView.as_view(), name='knox_logout'),

    path('api/token/', TokenObtainPairView.as_view()),
    path('api/token/refresh', TokenRefreshView.as_view())
]

Ответы [ 2 ]

1 голос
/ 29 июня 2019

Если вы используете UserDataSerializer в представлении API, то get_object() должен возвращать экземпляр модели UserData, чтобы его сериализатор знал, какие поля сериализовать и как получить его значение.

Попробуйте, я надеюсь, что это решит вашу проблему.

class UserAPI(generics.RetrieveAPIView):
    permission_classes = [ permissions.IsAuthenticated,]
    serializer_class = UserDataSerializer
    queryset = UserData.objects.all()

    def get_object(self):
        return self.request.user.userdata

Рекомендация:

Вы должны создать UserSerializer сериализатор и выполнить обратную сериализацию UserData сериализации модели в UserSerializer, потому что Модель пользователя всегда будет иметь экземпляр для каждого пользователя, но это дополнительная информация, которую вы сохраняете в модели UserData , которая может существовать или не существовать.ТАК, лучше сериализовать первичный ресурс.Тогда ваши данные будут выглядеть так, что, конечно, вы можете изменить их структуру так, как вам нравится.

{
  "id": 1,
  "email": "email@email.com",
  "username": "myusername",
  "userdata": {
    "currency": "USD",
    "budget": 500,
    "showCategories": true,
    "showLocations": true,
    "showSources": true
  }
}
1 голос
/ 29 июня 2019

Не уверен, как ваш UserAPI просмотр вернул результат без определенного queryset

Попробуйте это

class UserAPI(generics.RetrieveAPIView):
    permission_classes = [ permissions.IsAuthenticated,]
    serializer_class = UserDataSerializer
    queryset = UserData.objects.all()
    lookup_field = 'pk'

В зависимости от вашей версии Django ваша конечная точка URL должна содержать lookup_field, которая обычно равна pk по умолчанию для DRF.

url(r'^user/(?P<pk>\d+)/$', views.User.as_view())

Таким образом, доступ к ...../user/4/ возвращает экземпляр UserData с идентификатором 4.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...