Изменение информации в панели администрирования Django
Я новичок в программировании и пишу свой пет-проект. Я пишу код для изменения репутации пользователя при взятии книги в аренду. Вот ключевой код из модели
class BooksRent(models.Model):
"""Модель выдачи книг.
||
Book lending model."""
book = models.ForeignKey(
Books,
verbose_name='Книга',
help_text='Укажите Книгу',
on_delete=models.SET_NULL,
null=True,
related_name='rents'
)
reader = models.ForeignKey(
Readers,
verbose_name='Читатель',
help_text='Укажите Читателя',
on_delete=models.SET_NULL,
null=True
)
rented_at = models.DateTimeField(
verbose_name='Дата выдачи книги',
help_text='Укажите дату выдачи книги читателю',
# auto_now_add=True
)
returned_at = models.DateTimeField(
null=True,
blank=True,
verbose_name='Дата возврата книги',
help_text='Укажите дату возврата книги читателем',
)
class Meta():
ordering = ('reader',)
verbose_name = 'Книгу в аренде'
verbose_name_plural = 'Книги в аренде'
def __str__(self):
return f"{self.reader.username} взял {self.book.title}"
def is_late(self):
if not self.returned_at:
return False
rental_duration = self.returned_at - self.rented_at
return rental_duration.days > 10
def save(self, *args, **kwargs):
# проверяем, возвращена ли книга вовремя
if self.returned_at:
is_returned_on_time = self.is_late()
if is_returned_on_time:
self.reader.reputation += 1
else:
self.reader.reputation -= 1
self.reader.save()
super().save(*args, **kwargs)
Так же есть метод в представлении:
class RentLateReturnViewSet(viewsets.ModelViewSet):
"""Аренда/Возврат книги.
||
Book rental/return viewset.
"""
pagination_class = PageNumberPagination
permission_classes = (IsAdminModeratorOrSuperUser, )
queryset = BooksRent.objects.all()
serializer_class = BooksRentSerializer
def list(self, request):
"""Запрет доступа к списку арендованных книг для всех,
кроме администраторов,
модераторов и суперпользователей. """
if not request.user.is_superuser and not request.user.is_staff:
raise PermissionDenied
return super().list(request)
def post(self, request):
data = request.data
book_id = data.get('book_id')
reader_id = data.get('reader_id')
rented_at = data.get('rented_at')
returned_at = data.get('returned_at')
book = get_object_or_404(Books, id=book_id)
# Ищем аренду, соответствующую переданным данным
# Создаем запись об аренде
rent = BooksRent.objects.create(
book=book, reader_id=reader_id,
rented_at=rented_at, returned_at=returned_at
)
if not rent:
return Response(status=status.HTTP_404_NOT_FOUND)
# Проверяем, была ли книга возвращена вовремя
if rent.is_late():
rent.reader.reputation -= 1
else:
rent.reader.reputation += 1
rent.reader.save()
rent.returned_at = timezone.now()
rent.save()
return Response(status=status.HTTP_200_OK)
На всякий случай прикладываю модель пользователя/читателя
class Readers(AbstractUser):
"""Модель Юзера/Читателя/Посетителя библиотеки.
||
Library User/Reader/Visitor Model.
"""
USER_ROLE = 'reader'
MODERATOR_ROLE = 'moderator'
ADMIN_ROLE = 'admin'
ROLE_CHOICES = (
(USER_ROLE, 'reader'),
(MODERATOR_ROLE, 'moderator'),
(ADMIN_ROLE, 'admin')
)
username = models.CharField(
verbose_name='Username',
max_length=100,
unique=True,
validators=(UnicodeUsernameValidator(), ),
help_text='Введите username пользователя'
)
first_name = models.CharField(
verbose_name='Имя читателя',
max_length=50,
help_text='Введите Имя'
)
last_name = models.CharField(
verbose_name='Фамилия читателя',
max_length=50,
help_text='Введите Фамилию'
)
email = models.EmailField(
unique=True,
verbose_name='email читателя',
help_text='Введите электронную почту'
)
phone_number = PhoneNumberField(
unique=True,
null=False,
blank=False,
)
reputation = models.IntegerField(
default=10,
verbose_name='Рейтинг Читателя'
)
role = models.CharField(
max_length=max((len(item) for _, item in ROLE_CHOICES)),
choices=ROLE_CHOICES,
default=USER_ROLE,
verbose_name='Пользовательская роль',
help_text='Выберите роль пользователя'
)
class Meta:
ordering = ('username', )
verbose_name = 'Читатель'
verbose_name_plural = 'Читатели'
def __str__(self):
return self.username
@property
def is_moderator(self):
"""True для пользователей с правами модератора. """
return self.role == Readers.MODERATOR_ROLE
@property
def is_admin(self):
"""True для пользователей с правами админа и суперпользователей. """
return (
self.role == Readers.ADMIN_ROLE
or self.is_staff
or self.is_superuser
)
Для теста диапазон дней в аренде книги указан как 10. Тестируя код в админке django я указываю дату взятия книгу и дату возврата так, чтобы срок аренды превышал 10 дней, соответственно репутация пользователя должна понизиться на 1. Но этого не происходит. В админке я захожу в читателей и вижу, что репутация не изменилась. В чем может быть дело?
u.p.d. начал кидать запросы на API. Объект аренды создается, но репутация не меняется.
Метод подсчета репутации пытался выполнить как в модели так и в представлении.
Как видно из кода и скриншотов, дефолтное значение репутации, как было 10 так и осталось, увы репутация не изменилась.
З.Ы. данные пользователя тестовые и не имеют реального пользователя.