Форум сайта python.su
Вызываю у класса метод raw(), в нём пишу необходимый sql. Этот метод возвращает мне объект RawQuerySet. Есть ситуация, при которой в сыром запросе меньше полей чем у объекта, тогда у поля объекта этот объект становится как бы Deffered.
Как можно после вызова метода присвоить вручную значение полю объекта.
Код, для понимания:
from django.db import models class Password(models.Model): password = models.CharField(max_length=100) login = models.OneToOneField('Login') class Meta: db_table = 'passwords' class Login(models.Model): login = models.CharField(max_length=100, unique=True) class Meta: db_table = 'logins' gender = ( ('m', 'man'), ('w', 'woman'), ) class CustomUser(models.Model): login = models.OneToOneField(Login) password = models.OneToOneField(Password) email = models.EmailField(max_length=100) gender = models.CharField(max_length=5, choices=gender) class Meta: db_table = 'custom_user' class Achievement(models.Model): name = models.CharField(max_length=100) cost = models.FloatField(blank=True) login = models.ForeignKey(Login) class Meta: db_table = 'achievement'
>>> from app_convertation.models import * >>> res = CustomUser.objects.raw("""SELECT logins.id as id, '' as email, '' as gender, achievement.name as name FROM logins JOIN passwords ON passwords.login_id = logins.id JOIN achievement ON logins.id = achievement.login_id""") >>> res[0] <CustomUser_Deferred_login_id_password_id: CustomUser_Deferred_login_id_password_id object> >>> res[0].login # как теперь вручную присвоить этому атрибуту значение? Traceback (most recent call last): File "<input>", line 1, in <module> File "C:\Python33\lib\site-packages\django\db\models\fields\related.py", line 303, in __get__ val = self.field.get_local_related_value(instance) File "C:\Python33\lib\site-packages\django\db\models\fields\related.py", line 995, in get_local_related_value return self.get_instance_value_for_fields(instance, self.local_related_fields) File "C:\Python33\lib\site-packages\django\db\models\fields\related.py", line 1010, in get_instance_value_for_fields ret.append(getattr(instance, field.attname)) File "C:\Python33\lib\site-packages\django\db\models\query_utils.py", line 114, in __get__ instance._state.db).get(pk=instance.pk), File "C:\Python33\lib\site-packages\django\db\models\query.py", line 307, in get self.model._meta.object_name) app_convertation.models.DoesNotExist: CustomUser matching query does not exist. >>> res[0].login = Login.objects.get(pk=1) >>> res[0].login Traceback (most recent call last): File "<input>", line 1, in <module> File "C:\Python33\lib\site-packages\django\db\models\fields\related.py", line 303, in __get__ val = self.field.get_local_related_value(instance) File "C:\Python33\lib\site-packages\django\db\models\fields\related.py", line 995, in get_local_related_value return self.get_instance_value_for_fields(instance, self.local_related_fields) File "C:\Python33\lib\site-packages\django\db\models\fields\related.py", line 1010, in get_instance_value_for_fields ret.append(getattr(instance, field.attname)) File "C:\Python33\lib\site-packages\django\db\models\query_utils.py", line 114, in __get__ instance._state.db).get(pk=instance.pk), File "C:\Python33\lib\site-packages\django\db\models\query.py", line 307, in get self.model._meta.object_name) app_convertation.models.DoesNotExist: CustomUser matching query does not exist.
Отредактировано buddha (Фев. 7, 2014 16:20:08)
Офлайн
Можно попробовать грохнуть сначала.res[0].login = Login.objects.get(pk=1)
del res[0].login res[0].login = ...
Отредактировано PanovSergey (Фев. 7, 2014 17:01:21)
Офлайн
Интересный костыльный метод, спс=) Хочется чего то нативного, если имеется конечно таковое
Отредактировано buddha (Фев. 7, 2014 20:04:47)
Офлайн
type(res[0].login)
list(res)[0].login = ...
list(res)
res[0].login
login = models.OneToOneField(Login)
Отредактировано PanovSergey (Фев. 7, 2014 20:26:07)
Офлайн
Позже проверю…
Офлайн
У вас точно какая то фигня с данными
from django.test import TestCase from testapp.models import CustomUser, Login, Password, Achievement class TestRawDeferred(TestCase): def setUp(self): self.login = Login.objects.create(login="uTest") self.password = Password.objects.create(password="testpassword", login=self.login) self.user = CustomUser.objects.create(login=self.login, password=self.password, email="email@rmail.ru", gender="m" ) self.achievement = Achievement.objects.create(name="test", login=self.login, cost="22.0" ) def test_login(self): res = CustomUser.objects.raw("""SELECT logins.id as id, '' as email, '' as gender, achievement.name as name\ FROM logins JOIN passwords ON passwords.login_id = logins.id\ JOIN achievement ON logins.id = achievement.login_id""") print res[0] print res[0].login
(env)spanov@spanov-Aspire-7560G:/opt/develop/python.su/project/python.su$ make test
python manage.py test
Creating test database for alias 'default'...
CustomUser_Deferred_login_id_password_id object
Login object
.
----------------------------------------------------------------------
Ran 1 test in 0.008s
OK
Destroying test database for alias 'default'...
Отредактировано PanovSergey (Фев. 8, 2014 14:52:27)
Офлайн
Мои соображения по этому поводу:
1) Использую MySql\Postrges, Windows 7, python 3.3, django 1.6.1
2) вот странно как то в этой строке
print res[0].login Login object
Офлайн
1) Использую MySql\Postrges, Windows 7, python 3.3, django 1.6.1На результат теста это не влияет.
Откуда там взялся объект? ведь из запроса ничего не приходит. У меня то ломается и это более логично…Посмотрите доки
Отредактировано PanovSergey (Фев. 10, 2014 08:55:09)
Офлайн
Вот , уяснил. Я этого не делаю.
self.user = CustomUser.objects.create(login=self.login, password=self.password, email="email@rmail.ru", gender="m" )
>>> del res[0].login Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: __delete__
Офлайн