Добавление значений в ManyToManyField через администратора Django

Я новичок в Django, так что не могли бы вы помочь мне понять, как работает метод save()?

Вот мои модели:

class Tag(models.Model):
    name = models.CharField(verbose_name=u'Tag', max_length=200, unique=True)

class Entry(models.Model):
    title = models.CharField(verbose_name=u'Entry title', max_length=200)
    # some more fields here
    tags_string = models.CharField(verbose_name=u'Tags', max_length=200, blank=True)
    tags = models.ManyToManyField(Tag, blank=True)

Есть tags_string, где пользователь вводит теги через запятую. Это просто строка.

Затем я пытаюсь добавить теги в ManyToManyField, нажав «Сохранить» в админке Django:

def save(self):
    super(Entry, self).save()
    if self.tags_string:
        for tag in tags_string.split(","):
            t = Tag.objects.create(name=tag)
            self.tags.add(t)

но это не работает. entry.tags.add(t) отлично работает через оболочку Django — добавляет значения в базу данных. Я думаю, что что-то не так в моем методе save().

Не могли бы вы предложить мне, как это исправить, пожалуйста?


person elky    schedule 23.11.2011    source источник
comment
куда ты заливаешь self.tags_string?   -  person juliomalegria    schedule 23.11.2011
comment
В админке джанго. это просто CharField, который позже анализируется в методе save().   -  person elky    schedule 23.11.2011
comment
Я бы попробовал print self.tags_string .. может в этом проблема. Все остальное вроде правильно   -  person juliomalegria    schedule 23.11.2011
comment
print self.tags_string возвращает строку. Ничего страшного. также здесь успешно создаются теги: t = Tag.objects.create(name=tag) и сохраняются в базе данных. но таблица отношений entry_tags пуста.   -  person elky    schedule 23.11.2011
comment
Иногда я видел странное поведение с полями m2m в django... оно вообще ведет себя по-другому, если вы переключаетесь на другую базу данных (например, sqlite?)? Или вы можете сделать минимальное воспроизведение без другого кода?   -  person hwjp    schedule 23.11.2011


Ответы (3)


попробуй это

def save(self):
    super(Entry, self).save()
    if self.tags_string:
        for tag in tags_string.split(","):
            self.tags.create(name=tag)
person Paulo    schedule 23.11.2011

Проверить формат тегов M2M и распечатать их?

def save(self):
   super(Entry, self).save()
   if self.tags_string:
       print self.tags,type(self.tags)   
       for tag in tags_string.split(","):
          .......
person Nava    schedule 23.11.2011
comment
print self.tags,type(self.tags) возвращает следующее: ‹django.db.models.fields.related.ManyRelatedManager object at 0x9c905ac› ‹class 'django.db.models.fields.related.ManyRelatedManager'› - person elky; 23.11.2011

Во-первых, save имеет дополнительные параметры, которые необходимо учитывать. Во-вторых, вы должны использовать get_or_create вместо create для тегов:

def save(self, *args, **kwargs):
    super(Entry, self).save(*args, **kwargs)
    if self.tags_string:
        for tag in tags_string.split(","):
            t, created = Tag.objects.get_or_create(name=tag)
            self.tags.add(t)

Это может не решить текущую проблему, но в конечном итоге это помогло бы вам.

Вам также, вероятно, следует выполнить некоторую нормализацию тегов, используя str.lower() или title() из django.template.defaultfilters. В противном случае вы получите «Tag», «tag», «TAG» и «tAg».

person Chris Pratt    schedule 23.11.2011
comment
Большое спасибо, Крис. Это все еще не работает, но выглядит намного лучше :) - person elky; 23.11.2011