Наследование модели Джанго странное или ожидаемое поведение? - PullRequest
0 голосов
/ 16 января 2019

В настоящее время я работаю над проектом, использующим django 1.11, и некоторое время пытался найти причину ошибки. Я не знаю, является ли это ошибкой или ожидаемым поведением, и надеялся, что кто-нибудь сможет пролить свет на проблему или указать мне правильное направление. Я уже искал похожие проблемы, но ничего подобного не нашел.

Проблема в следующем, у меня есть базовая модель класса:

class BaseModel(models.Model):

    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    created_at = models.DateTimeField(default=timezone.now, editable=False)
    modified_at = models.DateTimeField(default=timezone.now, editable=False)

    def save(self, *args, **kwargs):
       if self.pk:
           self.modified_at = timezone.now
       return super(BaseModel, self).save(*args, **kwargs)

и она работала нормально на каждой модели, пока мне не пришлось переопределить поведение сохранения по умолчанию на другой модели:

class Agent(BaseModel):
    TIME_ZONES = [(tz, tz) for tz in pytz.common_timezones]

    user = models.OneToOneField(
        User,
        on_delete=models.CASCADE,
        related_name='agent',
    )

    time_zone = models.CharField(choices=TIME_ZONES,
                                 default=settings.TIME_ZONE,
                                 max_length=100)

    phone = models.CharField(max_length=50, null=True, blank=True)
    email = models.CharField(max_length=255, null=True, blank=True)

    def __str__(self):
        return self.user.username

    def save(self, *args, **kwargs):
        self.email = self.user.email
        return super(Agent, self).save(*args, **kwargs)

Когда я попытался сохранить новый экземпляр модели Agent в БД, выполнив Agent(user=user).save(), возникла исключительная ситуация, говорящая expected string or bytes-like object.

Исключение не возникает, если я выполняю одно из следующих действий:

  • Измените модель Agent так, чтобы она наследовалась непосредственно от models.Model, и объявите класс 'create_at andified_at in the Agent`
  • Измените супер вызов метода сохранения класса Agent на super(BaseModel, self).super(*args, **kwargs) и все еще наследуйте от BaseModel

Как я уже говорил, я не знаю, упускаю ли я что-то, и это ожидаемое поведение или это ошибка. Заранее спасибо за помощь.

Полный возврат:

Traceback:  

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
41.             response = get_response(request)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
187.                 response = self.process_exception_by_middleware(e, request)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/views/decorators/csrf.py" in wrapped_view
58.         return view_func(*args, **kwargs)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/views/generic/base.py" in view
68.             return self.dispatch(request, *args, **kwargs)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapper
67.             return bound_func(*args, **kwargs)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/views/decorators/debug.py" in sensitive_post_parameters_wrapper
76.             return view(request, *args, **kwargs)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/utils/decorators.py" in bound_func
63.                 return func.__get__(self, type(self))(*args2, **kwargs2)

File "/var/task/backend/users/views/sign_up.py" in dispatch
19.         return super(SignUpViewSet, self).dispatch(*args, **kwargs)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
483.             response = self.handle_exception(exc)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/rest_framework/views.py" in handle_exception
443.             self.raise_uncaught_exception(exc)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/rest_framework/views.py" in dispatch
480.             response = handler(request, *args, **kwargs)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/rest_framework/generics.py" in post
192.         return self.create(request, *args, **kwargs)

File "/var/task/backend/users/views/sign_up.py" in create
31.         user = self.perform_create(serializer)

File "/var/task/backend/users/views/sign_up.py" in perform_create
41.         user = serializer.save(self.request)

File "/var/task/backend/users/serializers/sign_up.py" in save
40.         agent.save()

File "/var/task/backend/users/models/agent.py" in save
31.         return super(Agent, self).save(*args, **kwargs)

File "/var/task/backend/core/models.py" in save
69.         return super(BaseModel, self).save(*args, **kwargs)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/base.py" in save
806.                        force_update=force_update, update_fields=update_fields)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/base.py" in save_base
836.             updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/base.py" in _save_table
903.                                       forced_update)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/base.py" in _do_update
953.         return filtered._update(values) > 0

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/query.py" in _update
661.         return query.get_compiler(self.db).execute_sql(CURSOR)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
1191.         cursor = super(SQLUpdateCompiler, self).execute_sql(result_type)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in execute_sql
863.             sql, params = self.as_sql()

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/sql/compiler.py" in as_sql
1157.                 val = field.get_db_prep_save(val, connection=self.connection)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/fields/__init__.py" in get_db_prep_save
766.                                       prepared=False)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/fields/__init__.py" in get_db_prep_value
1455.             value = self.get_prep_value(value)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/fields/__init__.py" in get_prep_value
1434.         value = super(DateTimeField, self).get_prep_value(value)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/fields/__init__.py" in get_prep_value
1292.         return self.to_python(value)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/db/models/fields/__init__.py" in to_python
1395.             parsed = parse_datetime(value)

File "/root/.virtualenvs/ve/lib/python3.6/site-packages/django/utils/dateparse.py" in parse_datetime
94.     match = datetime_re.match(value)

Exception Type: TypeError at /api/v1/auth/sign-up/
Exception Value: expected string or bytes-like object

1 Ответ

0 голосов
/ 16 января 2019
self.modified_at = timezone.now

Это ваша проблема. Вы хотели сделать timezone.now(). Это происходит сбой при разборе даты из ссылки на функцию вместо строки или объекта datetime. Вы не активируете поведение, если пропустите метод сохранения из класса BaseModel.

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