Аналогично определенные классы моделей Django ведут себя странным образом - PullRequest
0 голосов
/ 25 февраля 2012

Поведение, которое я не могу объяснить:
Я следую учебнику по djangobook.com и подключил простую унаследованную базу данных mysql.
Я определил модель так:

class Sentences(models.Model):
    sentenceid = models.IntegerField(primary_key=True)
    sentence = models.TextField(blank=True)
    class Meta:
        db_table = u'sentences'

    def __unicode__(self):
        return unicode(self.sentence)

class Character(models.Model):
    charid = models.IntegerField(primary_key=True)
    symbol = models.TextField(blank=True)
    class Meta:
        db_table = u'characters'

    def __unicode__(self):
        return unicode(self.symbol)

Довольно стандартные вещи.

Я тестирую доступ к нему через оболочку. Символы возвращаются красиво, но предложения действуют странно, несмотря на то, что они определены (как мне кажется) совершенно одинаково.

>>> from myapp.models import Character
>>> c = Character.objects.filter(charid=70)
>>> c 
[<Character: β>]

Это прекрасно, но:

>>> from myapp.models import Sentences
>>> s = Sentences.objects.get(sentenceid=25)
>>> s
<Sentences: Sentences object>
>>> print s
Sentences object
>>> print s.sentence
The quick brown fox jumps over the lazy dog. 

Почему он не возвращает предложение в первом случае? Почему я должен использовать s.sentence вместо этого?
Это слишком долго?
Я обнаружил, что s.sentence работает случайно.

1 Ответ

0 голосов
/ 26 февраля 2012

ОБНОВЛЕНИЕ: у вас есть другая проблема. Здесь, с вашим кодом модели:

class Sentences(models.Model):
    sentenceid = models.IntegerField(primary_key=True)
    sentence = models.TextField(blank=True)
    class Meta:
        db_table = u'sentences'

    def __unicode__(self):
        return unicode(self.sentence)

__unicode__ отлично работает:

In [1]: from testapp.models import Sentences

In [2]: Sentences(sentence='foo').save()
DEBUG (0.000) INSERT INTO "sentences" ("sentenceid", "sentence") VALUES (None, foo); args=(None, 'foo')

In [3]: Sentences.objects.all()
DEBUG (0.000) SELECT "sentences"."sentenceid", "sentences"."sentence" FROM "sentences" LIMIT 21; args=()
Out[3]: [<Sentences: foo>]

Еще одна попытка с более длинным предложением:

In [1]: from testapp.models import Sentences

In [2]: Sentences(sentence='The quick brown fox jumps over the lazy dog. ').save()
DEBUG (0.000) INSERT INTO "sentences" ("sentenceid", "sentence") VALUES (None, The quick brown fox jumps over the lazy dog. ); args=(None, 'The quick brown fox jumps over the lazy dog. ')

In [3]: Sentences.objects.all()
DEBUG (0.000) SELECT "sentences"."sentenceid", "sentences"."sentence" FROM "sentences" LIMIT 21; args=()
Out[3]: [<Sentences: foo>, <Sentences: The quick brown fox jumps over the lazy dog. >]

Поэтому, пожалуйста, проверьте, что:

  1. Вы перезапустили оболочку после добавления Юникод определение

  2. Sentences.__module__ возвращает правильный app.class (здесь: testapp.models)

  3. что Sentences.__unicode__ определено

Это работает:

In [9]: Sentences.__unicode__
Out[9]: <unbound method Sentences.__unicode__>

Не удалось:

In [1]: from testapp.models import Sentences

In [2]: Sentences.__unicode__
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/home/jpic/testproject/<ipython-input-2-dcbda9dfb929> in <module>()
----> 1 Sentences.__unicode__

AttributeError: type object 'Sentences' has no attribute '__unicode__'

КОНЕЦ ОБНОВЛЕНИЯ

filter () возвращает QuerySet , который похож на список объектов . Таким образом, скобки вокруг значения [<Character: β>]:

>>> Character.objects.filter(charid=70)
[<Character: β>]

Если бы вы использовали get () , вы бы напрямую получили экземпляр Character

>>> Character.objects.get(charid=70)
<Character: β>

Модель символов имеет атрибут TextField 'symbol' , к которому можно получить доступ, например:

>>> Character.objects.get(charid=70).symbol
u'β'

Вы понимаете, что совершенно нормально, что Sentences.objects.get () возвращает один объект Sentences :

>>> Sentences.objects.get(sentenceid=25)
<Sentences: Sentences object>

Теперь ваша модель Sentences имеет атрибут TextField «предложение» , к которому вы можете получить доступ как таковой:

>>> Sentences.objects.get(sentenceid=25).sentence
The quick brown fox jumps over the lazy dog. 

Все работает, и поведение соответствует.

...