Avi Gupta
Avi Gupta

Reputation: 15

Data is not saving to the database but shows on terminal in Django

So i have been trying to add Tags using django-taggit, but for some reason tags are not saving to the database when i try to upload a post using website but it works perfectly with django admin(Tags are saving to the database).

Also when i go to my Post_edit view and try to update empty tags field then it works. In other words, tags are only saving to the database when i try to edit it using Postedit view or upload it using admin. I want it to save to the database using PostUpload view only(like i have to use PostEdit view for every post to display tags). I think there's something wrong either with my view or form.

Also i can see request.POST data is returning the list of Tags on the terminal and form returns no errors.

Everything else is saving to the database except Tags.

here's my code

Views.py

Uploading Posts( views.py )

@login_required(login_url="/login/")
def post_upload(request):
    index1 = Blog.objects.all().order_by('-time')[0]
    content = request.POST.get('content')
    title = request.POST.get('title')
    image = request.FILES.get('image')
    if request.method == 'POST':
        post_form = PostUpload(request.POST, request.FILES, instance=request.user)
        if post_form.is_valid():
            tags = post_form.cleaned_data['tags']
            context = post_form.cleaned_data['context']
            excerpt_type = post_form.cleaned_data['excerpt_type']
            ins = Blog.objects.create(user=request.user, content=content, title=title, image=image, context=context,
                                      tags=tags, excerpt_type=excerpt_type)
            ins.save()
            messages.success(request, 'Your Post has been successfully posted')
            print(request.POST)
            print(tags)
            return HttpResponseRedirect(reverse('post_upload'))
        else:
            print(f'error in {request.POST}')
    else:
        post_form = PostUpload(instance=request.user)
    context = {'post_form': post_form, 'index1': index1}
    return render(request, 'post_upload.html', context)

For editing Posts( views.py )

@login_required(login_url="/login/")
def post_edit(request, pk):
    index1 = Blog.objects.all().order_by('-time')[0]
    post = get_object_or_404(Blog, pk=pk)
    user = request.user
    if request.method == 'POST':
        edit_form = PostEdit(request.POST or None, request.FILES, instance=post)
        if edit_form.is_valid():
            edit_form.save()
            print(request.POST)
            messages.success(request, 'Your Post has been updated successfully')
            return HttpResponseRedirect(post.get_absolute_url())
    else:
        edit_form = PostEdit(instance=post)
    context = {'edit_form': edit_form, 'post': post, 'user': user, 'index1': index1}
    return render(request, 'post_edit.html', context)

models.py

class Blog(models.Model):
    sno = models.AutoField(primary_key=True)
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    title = models.CharField(max_length=200)
    content = RichTextUploadingField()
    views = models.PositiveIntegerField(default=0)
    image = models.ImageField(upload_to='images/', blank=True, default="/static/img/900x300.png")
    slug = AutoSlugField(populate_from='title', unique=True, unique_with='title')
    time = models.DateTimeField(auto_now_add=True)
    excerpt_type = models.ForeignKey(Excerpt, on_delete=models.CASCADE, null=True, blank=True)
    context = models.CharField(max_length=20, null=True, blank=True)
    tags = TaggableManager()

    @property
    def image_url(self):
        if self.image and hasattr(self.image, 'url'):
            return self.image.url
        else:
            return "/static/images/900x300.png"

    @property
    def get_month_name(self):
        if self.time.month == 1:
            return 'January'
        elif self.time.month == 2:
            return 'February'
        elif self.time.month == 3:
            return 'March'
        elif self.time.month == 4:
            return 'April'
        elif self.time.month == 5:
            return 'May'
        elif self.time.month == 6:
            return 'June'
        elif self.time.month == 7:
            return 'July'
        elif self.time.month == 8:
            return 'August'
        elif self.time.month == 9:
            return 'September'
        elif self.time.month == 10:
            return 'October'
        elif self.time.month == 10:
            return 'November'
        elif self.time.month == 12:
            return 'December'

    def __str__(self):
        return self.title + ' by ' + self.user.username

    def get_absolute_url(self):
        return reverse("posts:posts", args=[str(self.slug)])

forms.py

class PostUpload(forms.ModelForm):
    class Meta:
        model = Blog

        exclude = ['slug', 'user', 'views']


class PostEdit(forms.ModelForm):
    class Meta:
        model = Blog

        exclude = ['slug', 'user', 'views']

blogposts.html

 {% if tag %}
                        <div class="sidebar-box ftco-animate">
                            <h3>Tag Cloud</h3>
                            <div class="tagcloud">
                                {% for tag in Blog.tags.all %}
                                    <a href="{% url 'tagged' tag.slug %}" class="tag-cloud-link">{{ tag }}</a>
                                {% endfor %}
                            </div>
                        </div>
                    {% endif %}

post_upload.html

{% block body %}
    <div class="container rounded bg-white mt-5 mb-5">
    <div class="col-md-8 mt-3">
    <form class="form-group" action="./" method="post" enctype="multipart/form-data"  >
    {% csrf_token %}

                    <label for="validationDefaultUsername">Username</label>
                    <div class="input-group">
                        <div class="input-group-prepend">
                            <span class="input-group-text" id="inputGroupPrepend2">@</span>
                        </div>
                        <input name="username" type="text" class="form-control" id="validationDefaultUsername"
                               value="{{ user.username }}" aria-describedby="inputGroupPrepend2" disabled>
                    </div>

        {{ post_form.errors | as_crispy_errors }}
        {{ post_form.media }}
        {{ post_form | crispy }}
    <input type="submit" value="Save changes" class="btn" style="color: blueviolet;">
</form>
    </div>
    </div>
    </div>
{% endblock body %}

post_edit.html

{% block body %}
    <div class="container rounded bg-white mt-5 mb-5">
        <div class="col-md-8 mt-3 mb-3">
            <form method="post" enctype="multipart/form-data" class="form-group">


                {% csrf_token %}

                    <label for="validationDefaultUsername">Username</label>
                    <div class="input-group">
                        <div class="input-group-prepend">
                            <span class="input-group-text" id="inputGroupPrepend2">@</span>
                        </div>
                        <input name="username" type="text" class="form-control" id="validationDefaultUsername"
                               value="{{ user.username }}" aria-describedby="inputGroupPrepend2" disabled>
                    </div>

                {{ edit_form.errors }}
                {{ edit_form.media }}
                {{ edit_form | crispy }}
                <input type="submit" value="Save changes" class="btn" style="color: blueviolet;">
            </form>
        </div>
    </div>
{% endblock body %}

Upvotes: 1

Views: 553

Answers (3)

Zulqarnain Naveed
Zulqarnain Naveed

Reputation: 108

You have to save the object first then split the tag values by comma and then add the tags into the field of your object this way. I have added the comments for your understanding. Views.py Uploading Posts( views.py )

@login_required(login_url="/login/")
def post_upload(request):
    index1 = Blog.objects.all().order_by('-time')[0]
    content = request.POST.get('content')
    title = request.POST.get('title')
    image = request.FILES.get('image')
    if request.method == 'POST':
        post_form = PostUpload(request.POST, request.FILES, instance=request.user)
        if post_form.is_valid():
            tags = post_form.cleaned_data['tags']
            context = post_form.cleaned_data['context']
            excerpt_type = post_form.cleaned_data['excerpt_type']
            # Removed tags=tags from the below line
            # Also, if you want to use `save` then you don't want to use
            # `create` as it will persist into your db right away.
            # Simply create an instance of Blog
            ins = Blog(user=request.user, content=content, title=title,
                        image=image, context=context,
                        excerpt_type=excerpt_type)
                # Adding tags against the object field after the object creation
            for tag in tags:
                ins.tags.add(tag)
            ins.save()
            
            messages.success(request, 'Your Post has been successfully posted')
            print(request.POST)
            print(tags)
            return HttpResponseRedirect(reverse('post_upload'))
        else:
            print(f'error in {request.POST}')
    else:
        post_form = PostUpload(instance=request.user)
    context = {'post_form': post_form, 'index1': index1}
    return render(request, 'post_upload.html', context)

Upvotes: 2

Ravi
Ravi

Reputation: 90

Inside post_upload method, are you sure you need instance=request.user to create a post_form object?

Upvotes: 0

Ayush Bansal
Ayush Bansal

Reputation: 485

You have to call form.save_m2m() to save tags when using django-taggit library like this:

    post_form = PostUpload(request.POST, request.FILES, instance=request.user)
    if post_form.is_valid():
        obj = post_form.save(commit=False)
        obj.save()
        # Without this next line the tags won't be saved.
        post_form.save_m2m()
        messages.success(request, 'Your Post has been successfully posted')
        print(request.POST)
        print(tags)
        return HttpResponseRedirect(reverse('post_upload'))

You can read more here.

Upvotes: 0

Related Questions