0

I want the user to be able to tag his post. So, he would enter words in the text field, and separate them with ",". When he is done, he presses save and all the tags he entered will be saved to that post. I am using django-taggit, but when the user enters his words in the field they do not get saved with the post. But when I do that from the django-admin site it works perfect.

Here is my code:

models.py:

class Post(models.Model):
    STATUS_CHOICES =   (
        ('draft', 'Draft'),
        ('published', 'Published'),    
    )

    title = models.CharField(max_length=250)
    slug = models.SlugField(max_length=250,
                            unique_for_date='publish')
    author = models.ForeignKey(settings.AUTH_USER_MODEL,
                               related_name='blog_posts')
    body = RichTextUploadingField()
    publish = models.DateTimeField(default=timezone.now)
    created = models.DateTimeField(auto_now_add=True)
    updated = models.DateTimeField(auto_now=True)
    status = models.CharField(max_length=10,
                              choices=STATUS_CHOICES,
                              default='draft')
    objects = models.Manager() # The default manager
    published = PublishedManager() # Our custom manager
    tags = TaggableManager()
    category = models.ForeignKey(BlogCategory, related_name='post_category')

    header_photo = models.ImageField(upload_to = 'users/%Y/%m/%d',   
                                        null = True,
                                        blank = True,
                                        width_field="width_field",
                                        height_field="height_field"
                                        )
    width_field = models.IntegerField(default = 0, null = True)
    height_field = models.IntegerField(default=0, null = True)

forms.py:

class CreatePostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ('title', 'status', 'header_photo', 'body', 'tags')

views.py:

@login_required(login_url='account_login')
def create_post(request):
    if request.method == 'POST':
        post_form = CreatePostForm(data=request.POST, files=request.FILES)
        if post_form.is_valid():
            new_post = post_form.save(commit=False)
            new_post.author = request.user
            profile = Profile.objects.get(profile_user=request.user)
            new_post.category = profile.type_of_blogger
            new_post.slug = slugify(new_post.title)
            new_post.save()
            messages.success(request, 'Post created successfully', extra_tags='post_saved')
            # redirect to new created item detail view
            return redirect(new_post.get_absolute_url())
    else:
        post_form = CreatePostForm()
    context = {'post_form': post_form}
    return render(request,
                  'blog/post/create_post.html',
                  context)

urls.py:

urlpatterns = [
    # post views
    url(r'^$', views.post_list, name='post_list'),
    url(r'^create/$', views.create_post, name='create_post'),
    url(r'^detail/(?P<id>\d+)/(?P<slug>[-\w]+)/$', views.post_detail, name='post_detail'),
]

My form in html:

<form class="form-horizontal text-center" method="post" action="." enctype="multipart/form-data">
                    {% csrf_token %}
                    {{ post_form.media }}
                    <fieldset>
                        <div class="container text-center" style="margin-bottom: 20px">
                            <h2 style="color: #c1b4b4;">Upload the header picture for your post</h2>
                            {% render_field post_form.header_photo style="background-color: #E8E8E8" %}
                        </div>
                        <div class="form-inline text-center">
                            <div class="form-group" style="margin-bottom: 20px;">
                                {% render_field post_form.title class="form-control" placeholder="Blog title" %}
                                {% render_field post_form.status class="form-control" %}
                                <p>Tag your post, so users can easy find it.</p>
                                {% render_field post_form.tags class="form-control" %}
                            </div>
                        </div>
                        {% render_field post_form.body class="form-control" %}
                        <hr>
                        <div class="control-group">
                            <!-- Button -->
                            <div class="controls" style="margin-bottom: 20px">
                                <button class="btn btn-lg btn-success" style="min-width: 300px">Save</button>
                            </div>
                        </div>
                        {% if redirect_field_value %}
                        <input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
                        {% endif %}
                     </fieldset>
                </form>

Thank you for your help.

P3P5
  • 923
  • 6
  • 15
  • 30

1 Answers1

1

Try to use save_m2m() method.

From docs:

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:

if request.method == "POST":
form = MyFormClass(request.POST)
if form.is_valid():
    obj = form.save(commit=False)
    obj.user = request.user
    obj.save()
    # Without this next line the tags won't be saved.
    form.save_m2m()
neverwalkaloner
  • 46,181
  • 7
  • 92
  • 100
  • hmmmm thank you for you response, I can't try it right now, but as soon as I do I will accept your answer. – P3P5 Nov 18 '16 at 17:35