Создание Django FloatField и DecimalField возвращает отличные от объекта в базе данных - PullRequest
0 голосов
/ 02 ноября 2018

Я только что понял, что в Django2 объект при создании (используя xxx.objects.create или xxx.save) возвращает объект, который немного отличается от объекта, который действительно находится в базе данных (MODEL.objects). .get ( объект создан )). Вы можете увидеть это используя DecimalField или FloatField:

class Product(Model):
     price = FloatField()

затем запуск оболочки (python manage.py shell):

from *project*.models import Product
a = Product.objects.create(price=30)
# or "a = Product(price=30); a.save()"
b = Product.objects.get(price=30)
a == b  # True
str(a.price) == str(b.price)  # False : "30" == "30.0"

Это ошибка от Django? Почему django не возвращает тот же объект?

Поскольку при создании объекта с использованием метода xxx.objects.create вы ожидаете, что он вернет тот же объект (по крайней мере, ту же копию), что и при поиске этого объекта в базе данных. Я нашел исходный код метода создания:

def create(self, **kwargs):
    """
    Creates a new object with the given kwargs, saving it to the database
    and returning the created object.
    """
    obj = self.model(**kwargs)
    self._for_write = True
    obj.save(force_insert=True, using=self.db)
    return obj

Большое спасибо!

РЕДАКТИРОВАТЬ: мой вопрос: почему оба объекта являются разными? Почему, когда я создаю объект, django не возвращает объект с плавающей точкой, а объект с целым числом?

РЕДАКТИРОВАТЬ: Спасибо @Willem Van Onsem

если вы создаете объект, вы назначаете атрибуты передаваемому объекту им (здесь 30). Принимая во внимание, что если вы выбираете данные, поля будут читать результат ответа базы данных и интерпретировать его (float30)

Но я все еще думаю, что лучше, если при создании Django вернет "интерпретировать данные". РЕДАКТИРОВАТЬ: я думаю, что я не прав: это было бы слишком волшебным, и питон не любит "магию".

1 Ответ

0 голосов
/ 02 ноября 2018

Это ошибка от Django? Почему django не возвращает тот же объект?

Нет . Это не ошибка. Если вы .create(..) объект, вы сначала создаете объект Model, а затем вызываете .save(). Но это означает, что поля принимают значение, которое вы им даете. 30 по умолчанию является int, что означает, что если вы запросите type(a.price), вы получите:

>>> type(a.price)
<class 'int'>

Если вы запрашиваете базу данных, например, с помощью Model.objects.get(price=30), вы, однако, создаете запрос, например, здесь запрос будет выглядеть так:

SELECT *
FROM project_price
WHERE price = 30

База данных будет отвечать последовательностью записей. Эти записи интерпретируются ORM Django, и различные поля будут создавать аналоги Python. Таким образом, для FloatField будет преобразована «строка», содержащая ответ базы данных, в float через to_python Метод [GitHub] .

Теперь в Python float и int - это два разных типа, но это не означает, что два таких объекта не могут быть эквивалентными, например:

>>> float(30) == int(30)
True

Но если мы конвертируем их в строки, то обе они дают разные строки:

>>> str(int(30))
'30'
>>> str(float(30))
'30.0'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...