Django, обновление столбца БД, rest_framework - PullRequest
0 голосов
/ 27 февраля 2020

Немного застрял при обновлении столбца в БД. Я отправляю put запрос на обновление столбца. Но возвращается ошибка.

assert isinstance (response, HttpResponseBase), (AssertionError: Ожидается, что Response, HttpResponse или HttpStreamingResponse будет возвращено из представления, но получено <class 'NoneType'>

здесь - внешний интерфейс. Отправка request.

updateInvoceProject(id, company_name){
    return axios.put(API_HANDLER.database_api + "api/v1/update-project", {id, company_name})
},

serializer.py

class InvocesSerializer(serializers.ModelSerializer):
    class Meta:
        model = Invoces
        fields = ("__all__")

view

@csrf_exempt 
@api_view(["PUT"])
def update(request):
    if request.method == "PUT":
        serializer = InvocesSerializer(data=request.data)
        if serializer.is_valid():
            invoce = Invoces.objects.get(id=serializer.data["id"])
            invoce.company_name = serializer.data["company_name"]
            invoce.save()

            return Response(serializer.data)

urls

urlpatterns = [
    #
    path("api/v1/update-project", invocesView.update, name="update-project"),
    #
]

Но, в конце концов, ошибка, о которой я упоминал выше, всплывает. Я что-то здесь упускаю?

1 Ответ

0 голосов
/ 27 февраля 2020

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

вы можете просто сделать это так, чтобы быть уверенным, что он будет возвращать что-либо во всех случаях.

@csrf_exempt 
@api_view(["PUT"])
def update(request):
    # if request.method == "PUT":
    # You don't have to check for method, since you already defined it
    # in api_view(...) decorator.
    serializer = InvocesSerializer(data=request.data)
    # Raises a ValidatinException which will be sent as a 400 response.
    serializer.is_valid(raise_exception=True)
    invoce = Invoces.objects.get(id=serializer.data["id"])
    invoce.company_name = serializer.data["company_name"]
    invoce.save()
    return Response(serializer.data)

Лучшее решение

Я предлагаю вам использовать DRF UpdateAPIView (Сделайте это способом DRF: D) , чтобы избежать подобных ошибок , а также чтобы не выполнять всю проверку и сериализацию вручную.

, например, следующим образом:

1. Оставьте свой InvocesSerializer и создайте еще один для обновления company_name

# Inside serializers.py
class InvocesCompanyNameUpdateSerializer(serializers.ModelSerializer):

    def to_representation(self, instance):
        return InvocesSerializer(instance).to_representation(instance)

    class Meta:
        model = Invoces
        fields = ('company_name',)

2. Создайте класс UpdateAPIView для этого сериализатора

# Inside views.py
class InvoiceUpdateCompanyNameAPIView(UpdateAPIView):
    http_method_names = ['put'] # This is only to allow PUT method on this view.
    serializer_class = InvocesCompanyNameUpdateSerializer
    queryset = Invoces.objects.all()

3. Теперь добавьте это представление с re_path к вашим URL.

# Inside urls.py
urlpatterns = [
    #
    # you have to add "pk" url path variable, so DRF use it internally to identify
    # which object you want to update.
    re_path(r"api/v1/update-project/(?P<pk>[\d]+)/", 
        invocesView.InvoiceUpdateCompanyNameAPIView.as_view(), 
        name="update-project"),
    #
]
...