Джанго каркас отдыха, смена ForeignKey - PullRequest
0 голосов
/ 19 мая 2018

Я слишком долго сражаюсь с DRF, так что теперь я должен задать вопрос .. Как изменить ForeignKey на другой?У меня есть профиль пользователя и отношение к модели состояния.

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    ldap_uid = models.CharField(max_length=100, blank=True, null=True, default=None)
    redmine_id = models.IntegerField(blank=True, null=True, default=None)
    status = models.ForeignKey(Status, models.SET_NULL, blank=False, null=True, default=DEFAULT_STATUS_ID)
    location = models.ForeignKey(Location, models.SET_NULL, blank=False, null=True, default=DEFAULT_LOCATION_ID)
    online = models.BooleanField(default=False)


class SelectValuesModel(models.Model):
    name = models.CharField(max_length=100)
    display_name = models.CharField(max_length=100)

    def __str__(self):
        return self.name

    class Meta:
        abstract = True


class Status(SelectValuesModel):
    pass


class Location(SelectValuesModel):
    pass

Какой хороший способ изменить статус профиля на другой?Я пытаюсь с чем-то вроде этого безуспешно

views.py

class UserStatusView(viewsets.ViewSet):
    def partial_update(self, request, pk=None):
        user = User.objects.get(pk=pk)
        user_profile = user.profile
        new_stauts = Status.objects.get(request.data.status)
        serialized_data = ProfileSerializer(user_profile)
        if(serialized_data.is_valid()):
            serialized_data.save(status=new_stauts)
        return Response(serialized_data.errors)

И пытаюсь отправить новый идентификатор через PATCH.Я пытаюсь найти решение, но безуспешно.И как это хорошо?Сделать другой маршрут для обновления статуса профиля?Или сделать что-то вроде профиля / 1 / update_status / 2?Теперь моя маршрутизация выглядит так:

router = routers.DefaultRouter()
router.register(r'users', views.UserViewSet)
router.register(r'redmine', views.RedmineCurrentTaskView, base_name='redmine')
router.register(r'parameters', views.ParametersView, base_name='parameters')
router.register(r'update_status', views.UserStatusView, base_name='update_status')
router.register(r'debug', views.DebugStatus, base_name='debug')

urlpatterns = [
    path('', views.index, name='index'),
    path('api/', include(router.urls))
]

И serializers.py

class SelectValuesSerializer(serializers.ModelSerializer):
    class Meta:
        fields = ('pk', 'name', 'display_name')


class LocationSerializer(SelectValuesSerializer):
    class Meta(SelectValuesSerializer.Meta):
        model = Location


class StatusSerializer(SelectValuesSerializer):
    class Meta(SelectValuesSerializer.Meta):
        model = Status


class ProfileSerializer(serializers.ModelSerializer):
    status = StatusSerializer()
    location = LocationSerializer()

    class Meta:
        model = Profile
        fields = ('status', 'location', 'online', 'redmine_id')


class UserSerializer(serializers.ModelSerializer):
    profile = ProfileSerializer(read_only=True)

    class Meta:
        model = User
        fields = ('pk', 'first_name', 'profile')
        read_only_fields = ('first_name',)

1 Ответ

0 голосов
/ 19 мая 2018

Просто передайте request.data в сериализатор с аргументом partial=True:

class UserStatusView(viewsets.ViewSet):
    def partial_update(self, request, pk=None):
        user = User.objects.get(pk=pk)
        user_profile = user.profile
        serialized_data = ProfileSerializer(user_profile, data=request.data, partial=True)
        if serialized_data.is_valid():
            serialized_data.save()
            return Response(serialized_data.data)
        return Response(serialized_data.errors)

Вам необходимо предоставить status_id с таким текстом запроса:

{"status": 1}

UPD

Чтобы передать статус в качестве идентификатора, измените ваш сериализатор на:

class ProfileSerializer(serializers.ModelSerializer):
    location = LocationSerializer()

    class Meta:
        model = Profile
        fields = ('status', 'location', 'online', 'redmine_id')

    def to_representation(self, instance):
        self.fields['status'] = StatusSerializer()
        return super(ProfileSerializer, self).to_representation(instance)

Это позволяет публиковать status_id, но получать информацию о статусе с помощью вашего API.

...