@Fedor_PV

Django-taggit теги, отправленные через форму, не сохраняются в базе данных, почему??

Django 2.0, Python 3.6.5. Подключил библиотеку django-taggit, изменил все как надо, по книжке Дронова, но как всегда ничего не работает: теги не сохраняются в базе данных. В документации, вычитал вот эту фразу:

If, when saving a form, you use the commit=False option you’ll need to call save_m2m() on the form after you save the object, just as you would for a form with normal many to many fields on it.

Отлично, сделал согласно документации, внес save_m2m() во view, все равно теги при отправке через форму не сохраняются в базе данных. Строчка Tags появляется в браузере, я ее заполняю, нажимаю "отправить", создается новый объект, со всеми характеристиками, кроме тегов!! Теги до базы данных не доходят почему-то! Не сохраняются в ней!

Через Shell проверяю только что внесенную запись - тегов НЕТ. Я уже с другой моделью экспериментировал (в представлении которой нет кода commit=False, где просто form.save() )- все равно теги не сохраняются в базе данных. ХОТЯ если через shell попробовать создать тег через код object.tags.add('') - все работает, тег появляется. Система на глубоком программном уровне работает. Но вот через форму не получается создать тег.

Все миграции базы данных давно успешно сделаны.
Как сохранить отправленные через форму теги в базе данных?

Модель:
from taggit.managers import TaggableManager
...
class Cities(models.Model):
country=models.ForeignKey(Countries, on_delete=models.CASCADE)
city_name=models.CharField(max_length=100)
tags = TaggableManager(blank=True, verbose_name='Теги')
class Meta:
    verbose_name_plural = 'ГОРОДА'  
def __str__(self):
    return self.city_name


from taggit.forms import TagField
...
class CitiesForm(forms.ModelForm):
    class Meta:
        model = Cities
        fields = ['city_name']
        labels = {'city_name': 'Type name of city'}
    tags=TagField(label='Tags')


def new_city(request, countries_id):
country=Countries.objects.get(id=countries_id)
if request.method != 'POST':
    form=CitiesForm()
else:
    form=CitiesForm(data=request.POST)
    if form.is_valid():
        new_city=form.save(commit=False)
        new_city.country=country
        new_city.save()
        form.save_m2m()
        return HttpResponseRedirect(reverse('countries:cities', args=[country.id]))
context={'country': country, 'form': form}
return render(request, 'countries/new_city.html', context)
  • Вопрос задан
  • 628 просмотров
Решения вопроса 1
@Fedor_PV Автор вопроса
Итак, господа, после нескольких часов танцов с бубном найдено решение! Чтобы принудительно сохранить теги в базе нужно на уровне функций представлений использовать цикл for для form.cleaned_data['tags'] и привязку тегов к объекту через код obj.tags.add(). На примере моей функции-представления, которая показана выше, рабочий код такой (может он и говнокод, но он РАБОТАЕТ, а лучше решения за сутки никто не смог предложить):
@login_required
def new_city(request, countries_id):
    country=Countries.objects.get(id=countries_id)
    if request.method != 'POST':
        form=CitiesForm()
    else:
        form=CitiesForm(data=request.POST)
        if form.is_valid():
            new_city=form.save(commit=False)
            new_city.country=country
            new_city.save()
            for tag in form.cleaned_data['tags']:
                new_city.tags.add(tag)
            ....


Потом вставляем в шаблон подобный код, как учил Дронов, и прекрасно все работает - теги сохраняются в базе через отправленную форму, прекрасно отображаются, через запятую, фильтруются, все отлично, господа!

{% with names=city.tags.names %}
      {% if names.count > 0 %}
         Tags: {% for name in names %}{% if not forloop.first %}, {% endif %} <a href="...?tag=..."> {{ name }} </a> {% endfor %}
      {% endif %}
    {% endwith %}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы