Change model field value after clicking an HTML button


(Jhon) #1

I am trying to implement a feature in which when I click on Activate button, the value in my Django database for this field changes to 'Active’ and is displayed on the HTML page as active. If deactivate is clicked, the text changes to deactive along with it’s value in the django database.

class Post(models.Model):
    submitted = models.ForeignKey(User, on_delete=models.CASCADE)
    ad_name = models.CharField(max_length=500)

    is_published = models.BooleanField(default=False) # i want this value change based on user action on html button.


(Immanuel) #2

You could do it this way. Add the following to your models.py file

# Create a custom manager
class ActivationManager(models.Manager):
    def get_queryset(self):
        return super(ActivationManager, self)\
            .get_queryset().filter(is_published='activated')

# Add the choices field option
class Post(models.Model):
    ACTIVATION_CHOICES = (
        ('activated', 'Activated'),
        ('deactivated', 'Deactivated')
    )
    ...
    is_published = models.CharField(
        maxlength=12, choices=ACTIVATION_CHOICES, default='deactivated'
    )
    ...
    objects = models.Manager() # the default manager
    activated = ActivationManager() # the custom manager

When trying to get all Activated Posts, you’ll do:

...
posts = Post.activated.all()
...

Hope this helps!


(Khalil Mehtal) #3

filter(is_published=‘activated’) instead of status because status isn’t defined


(Immanuel) #4

My bad. Fixed, thanks!


(Jhon) #5

I believe this is not what i asked for. I want html button to change the value in the database. Not get list of object based on status.


(Immanuel) #6

I’m sorry I misunderstood your issue. Not to worry, I came up with something. Here’s what I did:

urls.py

urlpatterns = [
    path('test/', views.test, name='test'),
    path('test/<int:pk>/', views.test_update, name='test_update')
]

models.py

class Test(models.Model):
    CHOICES = (
        ('activated', 'Activated'),
        ('deactivated', 'Deactivated'),
    )
    is_published = models.CharField(max_length=12, choices=CHOICES, default='deactivated')

    def __str__(self):
        return 'Test number {} is {}'.format(self.pk, self.is_published)

views.py

from .models import Test
from django.contrib import messages
from django.shortcuts import render, redirect, get_object_or_404
def test(request):
    published = Test.objects.all()
    return render(request, 'test.html', {'published':published})

def test_update(request, pk):
    published_item = get_object_or_404(Test, pk=pk)
    published_item.is_published = 'activated' if published_item.is_published == 'deactivated' else 'deactivated'
    published_item.save(update_fields=['is_published'])
    messages.success(request, 'Test number {} {} successfully'.format(pk, published_item.is_published))
    return redirect('test')

test.html

{% extends "base.html" %}

{% block content %}
    <h4>This is a test</h4>
    <ul class="uk-padding-bottom">
        {% for published_item in published %}
            <li>
                {{ published_item }}
                <a href="{% url 'test_update' pk=published_item.pk %}" class="uk-button uk-button-default">Update</a>
            </li>
        {% endfor %}
    <ul>
{% endblock %}

This should solve your issue.
NB class="uk-button uk-button-default" is from the library UIKit3


(Nehat Khan) #7

How should I try this method to update the value of the field in my table. For instance I would like to change the quantity of product from 10 to 5. How would I acheive that.


(Immanuel) #8

Please add a little more details


(Augustus Ezenwankwo ) #9

I think I may understand what you are trying to achieve.
You need to write a view function that should run when the user clicks on the button to effect whatever database changes you want.
On the front end, you then can use django template tag{% if … %} to display what you want the user to see. You can choose to implement this using ajax if you don’t want page refresh.