Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Django
  • » Что делать с полями Deffered, когда работаю с RawQuerySet. [RSS Feed]

#1 Фев. 7, 2014 16:14:29

buddha
От:
Зарегистрирован: 2012-03-02
Сообщения: 422
Репутация: +  15  -
Профиль   Отправить e-mail  

Что делать с полями Deffered, когда работаю с RawQuerySet.

Вызываю у класса метод 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)

Офлайн

#2 Фев. 7, 2014 17:01:02

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

Что делать с полями Deffered, когда работаю с RawQuerySet.

res[0].login = Login.objects.get(pk=1)
Можно попробовать грохнуть сначала.
del res[0].login
res[0].login = ...

Отредактировано PanovSergey (Фев. 7, 2014 17:01:21)

Офлайн

#3 Фев. 7, 2014 20:04:16

buddha
От:
Зарегистрирован: 2012-03-02
Сообщения: 422
Репутация: +  15  -
Профиль   Отправить e-mail  

Что делать с полями Deffered, когда работаю с RawQuerySet.

Интересный костыльный метод, спс=) Хочется чего то нативного, если имеется конечно таковое

Отредактировано buddha (Фев. 7, 2014 20:04:47)

Офлайн

#4 Фев. 7, 2014 20:10:07

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

Что делать с полями Deffered, когда работаю с RawQuerySet.

type(res[0].login)
полагаю тоже ломается?
А что если
list(res)[0].login = ...
 list(res) 
хотя бы работает?

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

res[0].login 
просто лезет в базу и подтягивает
login = models.OneToOneField(Login)
У вас просто похоже ошибка в данных он не может для этого CustomUser Login подтянуть.

Отредактировано PanovSergey (Фев. 7, 2014 20:26:07)

Офлайн

#5 Фев. 7, 2014 20:22:46

buddha
От:
Зарегистрирован: 2012-03-02
Сообщения: 422
Репутация: +  15  -
Профиль   Отправить e-mail  

Что делать с полями Deffered, когда работаю с RawQuerySet.

Позже проверю…

Офлайн

#6 Фев. 8, 2014 11:29:51

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

Что делать с полями Deffered, когда работаю с RawQuerySet.

У вас точно какая то фигня с данными

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)

Офлайн

#7 Фев. 10, 2014 08:48:51

buddha
От:
Зарегистрирован: 2012-03-02
Сообщения: 422
Репутация: +  15  -
Профиль   Отправить e-mail  

Что делать с полями Deffered, когда работаю с RawQuerySet.

Мои соображения по этому поводу:
1) Использую MySql\Postrges, Windows 7, python 3.3, django 1.6.1
2) вот странно как то в этой строке

print res[0].login
 
Login object
Откуда там взялся объект? ведь из запроса ничего не приходит. У меня то ломается и это более логично…

Офлайн

#8 Фев. 10, 2014 08:53:58

PanovSergey
От: Екатеринбург
Зарегистрирован: 2013-12-29
Сообщения: 269
Репутация: +  19  -
Профиль   Адрес электронной почты  

Что делать с полями Deffered, когда работаю с RawQuerySet.

1) Использую MySql\Postrges, Windows 7, python 3.3, django 1.6.1
На результат теста это не влияет.
Откуда там взялся объект? ведь из запроса ничего не приходит. У меня то ломается и это более логично…
Посмотрите доки
Суть в том что джанго лезет за недостающими полями при обращении.

Отредактировано PanovSergey (Фев. 10, 2014 08:55:09)

Офлайн

#9 Фев. 10, 2014 09:03:02

buddha
От:
Зарегистрирован: 2012-03-02
Сообщения: 422
Репутация: +  15  -
Профиль   Отправить e-mail  

Что делать с полями Deffered, когда работаю с RawQuerySet.

Вот , уяснил. Я этого не делаю.

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__

Офлайн

  • Начало
  • » Django
  • » Что делать с полями Deffered, когда работаю с RawQuerySet.[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version