Django - Удаление файла, связанного с атрибутом ImageField модели
Итак, у меня есть модель User
, в которой есть поле avatar
, которое является просто аватаром пользователя. Я хочу иметь возможность удалять файл всякий раз, когда пользователь решит удалить свой аватар. Как вы можете видеть ниже в моем view.py
я получаю объект текущего пользователя из request
(это потому, что я беру uuid пользователя из маркера доступа, предоставленного для выполнения запроса, а затем запрашиваю объект пользователя). Затем я вызываю delete
на атрибуте avatar
, но я не знаю, удаляет ли это файл. Я предполагаю, что он просто удаляет атрибут url
. Как мне удалить файл, связанный с ImageField, когда я удаляю атрибут ImageField в модели?
model.py
class User(AbstractDatesModel):
uuid = models.UUIDField(primary_key=True)
username = models.CharField(max_length=USERNAME_MAX_LEN, unique=True, validators=[
MinLengthValidator(USERNAME_MIN_LEN)])
created = models.DateTimeField('Created at', auto_now_add=True)
updated_at = models.DateTimeField('Last updated at', auto_now=True, blank=True, null=True)
avatar = models.ImageField(upload_to=avatar_directory_path, blank=True, null=True)
view.py
@api_view(['POST', 'DELETE'])
def multi_method_user_avatar(request):
if request.method == 'POST':
# Some POST code
elif request.method == 'DELETE':
try:
request.user.avatar.delete()
request.user.save()
return Response(status=status.HTTP_204_NO_CONTENT)
except Exception as e:
return Response(dict(error=str(e), user_message=generic_error_user_msg),
status=status.HTTP_400_BAD_REQUEST)
Удаление поля ImageField сохраняет файл в системе.
Измените свой код на следующий, чтобы удалить файл:
#insert at top of file
import os
elif request.method == 'DELETE':
try:
os.remove(request.user.avatar.path)
request.user.avatar.delete()
request.user.save()
request.user.avatar.delete()
достаточно. Я запустил тест, который проверяет, удален ли файл, и он прошел. Использование os.remove
не работает на развернутом сервере, потому что у вас нет доступа к их файловой системе на этом уровне.