#python-3.x #django #django-rest-framework
#python-3.x #django #django-rest-framework
Вопрос:
Все остальные поля обновляются правильно, кроме ImageField, который также не выдает никаких ошибок. В базе данных я вижу, что URL-адрес изображения обновляется, но в файловой системе изменений в media/
папке нет. Когда я использую модель, admin.site.register
все работает отлично (следовательно, я должен был правильно настроить MEDIA_ROOT и MEDIA_URL), и я вижу файл, загруженный в media
папку.
views.py
class ProfileView(generics.UpdateAPIView, generics.RetrieveAPIView):
queryset = Profile.objects.all()
serializer_class = ProfileSerializer
authentication_classes = [TokenAuthentication]
permission_classes = [IsAuthenticated]
def put(self, request):
print(request.data)
print(request.FILES)
p = Profile.objects.get(user=request.user)
serializer = ProfileSerializer(p)
serializer.update(p, request.data, request.user)
return Response(serializer.data)
def get(self, request):
p = Profile.objects.get(user=request.user)
serializer = ProfileSerializer(p)
return Response(serializer.data)
models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
firstName = models.CharField(max_length=50)
lastName = models.CharField(max_length=50)
dob = models.DateField(null=True, blank=True)
desc = models.CharField(max_length=500)
genderChoices = [('M', 'Male'), ('F', 'Female')]
gender = models.CharField(choices=genderChoices, max_length=1)
image = models.ImageField(blank=True, null=True)
def __str__(self):
return self.firstName " " self.lastName
serializers.py
class ProfileSerializer(serializers.ModelSerializer):
class Meta:
model = Profile
fields = ('firstName', 'lastName', 'dob', 'desc', 'gender', 'image', )
#TODO: write validators
def update(self, instance, validated_data, user):
p = Profile.objects.filter(user=user)
p.update(
firstName=validated_data['firstName'],
lastName=validated_data['lastName'],
dob=validated_data['dob'],
gender=validated_data['gender'],
image=validated_data['image'],
)
Я использую Postman для тестирования, и это ответ, который я получаю, с URL-адресом изображения, который не существует при его посещении.
Ответ №1:
Это потому, что вы используете QuerySet.update
метод для обновления своего изображения. Этот метод предназначен для обновления всего набора запросов. Этот метод выполняет запись непосредственно в базу данных, поэтому он пропускает много «волшебства», которое обычно происходит в фоновом режиме при вызове Model.save
метода. В частности, он пропускает всю обработку файла, включая сохранение этого файла в MEDIA_ROOT
каталоге. Используйте Model.save
вместо этого или обработайте сохранение файла в нужном месте вручную.
Кроме того, вам не нужно извлекать пользователя в этом методе, так как ваш сериализатор уже был вызван с profile в качестве аргумента, поэтому он должен быть доступен self.instance
внутри вашего метода обновления.
Комментарии:
1. А, понял. На днях у меня были небольшие проблемы, когда я пытался использовать
Profile.objects.get
метод with update и прочитал, что он работает только с набором запросов, если я правильно помню. Другой способ — сделать это вручнуюp.field = value
, а затемp.save()
правильно?2. Да, но сериализаторы DRF должны выполнять всю работу за вас, если вы используете их правильно.
Ответ №2:
установить ==> pip установить подушку
в settings.py добавить :
import os
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
в urls.py добавить:
from django.conf import settings
from django.conf.urls.static import static
if settings.DEBUG:
urlpatterns = static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
в моделях.py добавить:
image = models.ImageField(blank=True, null=True, upload_to='images')
в apiview добавьте context={«запрос»:запрос}:
def get(self, request):
p = Profile.objects.get(user=request.user)
serializer = ProfileSerializer(p, context={"request":request})
return Response(serializer.data)