Django get_foo_display not working as expected

Hi everyone, so I have been trying to code this and I have been seeing everyone’s code, I am pretty new to Django and not really sure how it works but what I am trying to do is display the choicefield value in template.

This is my models.py

class Orders(models.Model):
    order_choices = (
        ('王者', 'wangzhe'),
        ('小乔', 'xiaoqiao'),
        ('打野', 'da ye'),
        ('伽罗', 'jia luo'),
    )
    progress = (
        ("In Progress","In Progress"),
        ("Completed","Completed")
    )
    account = models.ForeignKey('users.AccountUser', on_delete=models.CASCADE)
    member = models.ManyToManyField('users.Member')
    order_type = models.CharField(max_length=255, choices=order_choices)
    status = models.CharField(max_length=50, choices=progress, default="In Progress")
    order_number = models.CharField(max_length=12, unique=True)
    
    def get_order_choices(self):
        return self.order_choices
        
    def get_progress(self):
        return self.progress
    
    def __str__(self):
        return self.order_type

While this is my views.py

from users.models import Member
from .forms import OrderForm
from .filters import OrderFilter
from .models import Orders

import os

@login_required
def services(request):
    if request.method == "POST":
        form = OrderForm(request=request, data=request.POST)
        if form.is_valid():
            order = form.save()
            messages.success(request, "Order Submitted!")
        else:
            for key, error in list(form.errors.items()):
                messages.error(request, error)
    else:
        form = OrderForm(request)
    
    choices = []
    for c in Orders.order_type.field.choices:
        choices.append(c[0])

    return render(
        request=request,
        template_name = "services/services.html",
        context={"form": form,
            "choices": choices,
            "member_id": request.user.member_id
        }
    )
    
@login_required
def orderSearch(request):
    orders = Orders.objects.all()
    
    myFilter = OrderFilter(request.GET, queryset=orders)
    orders = myFilter.qs
    
    return render(
        request=request,
        template_name = "services/orderSearch.html",
        context={
            "orders": orders,
            "myFilter": myFilter
        }
    )
    

and this is my template

<div class="container">
    <div class="row">
        <div class="content-section">
            {% for choice in choices %}
                <div class="col-md-4">
                  <div class="card">
                    <img class="card-img-top" src="{% static 'images/1.png' %}">
                    <div class="card-body">
                      <h5 class="card-title">{{choice}}</h5>
                      <p class="card-text">Description testing</p>
                      <!--<button id="openModal">Order Now</button>-->
                      <button class="openModal">Order Now</button>
                    </div>
                  </div>
                </div>
            {% endfor %}
            <div id="myModal" class="modal">
                <div class="modal-content">
                    <span class="close" id="closeModal">&times;</span>
                    <!-- Display the static information you want to show -->
                    <p> {{{ choice.get_order_choices_display }} </p>

                    <!-- Include your form here without an action attribute -->
                    <form method="post" id="modalForm" action="{% url 'services' %}">
                        {% csrf_token %}
                        <!-- Add your form fields here -->
                        <input type="hidden" name="member_id" id="id_member_id" value="{{ member_id }}">
                        <input type="hidden" name="order_type" id="id_order_type" value="补运">
                        
                        {{ form.member_name }}
                        <button type="submit" id="submitForm">Submit</button>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>

I am unable to get the display for the {{{ choice.get_order_choices_display }} inside the modal. My card title has no issue in displaying the names of the choicefield.

Do let me know if require more information

What is supposed to be rendered by choice.get_order_choices_display?

The English values such as “wangzhe”, “xiaoqiao” from the models. That is what I am trying to achieve. I am not sure is the way that I am coding it is right or not. I think it could be due to my views.py code that I am unable to achieve it?

One solution is instead of creating a choices list as you have it, you can create a choices list with dictionaires:

choices = []
for c in Orders.order_type.field.choices:
  d = {}
  d["english"] = c[1]
  d["non-english"] = c[0]
  choices.append(d)

Then in your template reference the english version as {{choice.english}}, and the non-english in your h5 tag for instance here as

{{choice.non-english}}
.

There also might be a better way but something along these lines should work.

Hi Michael, thanks for the solution. However, it did not for work exactly for the {{choice.english}} for my

tag that i used inside my modal. It kind of work by showing the first english value, “wangzhe” for all my modal that appeared after pressing button. I want all the modal output of english value to be based on the for loop as well

To help with more information, this are my js file, is it my JS have some issues when trying to load all the modal? Somehow when I click on any of the button to show the modal, it shows the same modal with static value of the english value “wangzhe” only.

// modal.js
document.addEventListener(‘DOMContentLoaded’, function () {
const openModalButtons = document.querySelectorAll(‘.openModal’);
//const openModalButton = document.getElementById(‘openModal’);
const modal = document.getElementById(‘myModal’);
const closeModalButton = document.getElementById(‘closeModal’);
const modalContent = document.querySelector(‘.modal-content’); // The modal content container

// Function to open the modal
function openModal() {
    modal.style.display = 'block';
}

// Function to close the modal
function closeModal() {
    modal.style.display = 'none';
}

// Add click event listeners to all buttons with the class 'openModalButton'
openModalButtons.forEach(function (button) {
    button.addEventListener('click', openModal);
});

// Close the modal when clicking the close button
closeModalButton.addEventListener('click', closeModal);

// Close the modal when clicking outside of it
document.body.addEventListener('click', function (event) {
    if (event.target === modal) {
        closeModal();
    }
});

// Prevent clicks inside the modal content from closing the modal
modalContent.addEventListener('click', function (event) {
    event.stopPropagation(); // Prevent the click event from bubbling up to the body
});

// Handle form submission (you can use AJAX here if needed)
const submitFormButton = document.getElementById('submitForm');
submitFormButton.addEventListener('click', function () {
    const formData = new FormData(document.getElementById('modalForm'));

    // You can use AJAX to send the form data to the server if needed
    // Example using fetch API:
    fetch('/your_submit_url/', {
        method: 'POST',
        body: formData,
    })
    .then(response => {
        // Handle the response from the server here if needed
    })
    .catch(error => {
        // Handle errors here if there's an issue with the request
    });
});

});

I’ve some code reference for you that will work

class MyChoice:
    feature_type = (
        (1, "How To Book"),
        (2, "Why Choose Us"),
        (3, "Privacy Policies"),
        (4, "Terms & Condition"),
    )


class SiteFeatures(Model):
    feature_type = models.IntegerField(choices=MyChoice().feature_type)
    description = HTMLField()

    @property
    def get_feature_type(self):
        for i in MyChoice().feature_type:
            if i[0] == self.feature_type:
                return i[1]
        return self.feature_type

It’s pretty simple I’ve created a property method that return the value of feature_type from the choices and then you can directly access this like other fields in templates

{{SiteFeatures.feature_type}}
{{SiteFeatures.description}}
{{SiteFeatures.get_feature_type}}
1 Like

Hey! Thanks for the code! It is similar to the code that michael have gave me, now my concerns is my modal is not working. Seems like it could be my JS not properly getting the choice.english over well

Do you have a repo I can take a look at?