Найти - Пользователи
Полная версия: Что делать с полями Deffered, когда работаю с RawQuerySet.
Начало » Django » Что делать с полями Deffered, когда работаю с RawQuerySet.
1
buddha
Вызываю у класса метод 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.
PanovSergey
res[0].login = Login.objects.get(pk=1)
Можно попробовать грохнуть сначала.
del res[0].login
res[0].login = ...
buddha
Интересный костыльный метод, спс=) Хочется чего то нативного, если имеется конечно таковое
PanovSergey
type(res[0].login)
полагаю тоже ломается?
А что если
list(res)[0].login = ...
 list(res) 
хотя бы работает?

Кстати глянул доки

res[0].login 
просто лезет в базу и подтягивает
login = models.OneToOneField(Login)
У вас просто похоже ошибка в данных он не может для этого CustomUser Login подтянуть.
buddha
Позже проверю…
PanovSergey
У вас точно какая то фигня с данными
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'...

Исходники
buddha
Мои соображения по этому поводу:
1) Использую MySql\Postrges, Windows 7, python 3.3, django 1.6.1
2) вот странно как то в этой строке
print res[0].login
 
Login object
Откуда там взялся объект? ведь из запроса ничего не приходит. У меня то ломается и это более логично…
PanovSergey
1) Использую MySql\Postrges, Windows 7, python 3.3, django 1.6.1
На результат теста это не влияет.
Откуда там взялся объект? ведь из запроса ничего не приходит. У меня то ломается и это более логично…
Посмотрите доки
Суть в том что джанго лезет за недостающими полями при обращении.
buddha
Вот , уяснил. Я этого не делаю.
self.user = CustomUser.objects.create(login=self.login,
                                              password=self.password,
                                              email="email@rmail.ru",
                                              gender="m"
                                              )

У меня такая логика, табличка модели CustomUser изначально пустая. У этой модели я создаю произвольный сырой запрос, со значениями из которого я потом сохраню экземпляры.

Логика дебильная, мне она не нравится, вот так просто построена работа с объектами вообще на другом языке в продакшене.

Спасибо за помощь, уже плюсанул =) вопрос закрываю, дальше копать нет смысла.

ПС: кстати попробовал удаление
>>> del res[0].login
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: __delete__
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB