Is there a more elegant solution?

  • 0
    Let's imagine there are two models models.py
    I need to display a list of all stores, but under each one display a list of phone numbers belonging to it. Solved for 2 days. And here's how I solved it ...
    class Store(models.Model):
        name = models.CharField(max_length=200)
        address = models.CharField(max_length=200)
    
    class Phones(models.Model):
        phone = models.CharField(max_length=50)
        store = models.ForeignKey(Store)

    vievs.py
    from django.shortcuts import render
    from .models import Store, Phones
    
    def get_store():
        stores = []
        for line in Store.objects.all():
            phone = line.phones_set.filter(show=1)
            l = []
            l.append(line)
            l.append(phone)
            stores.append(l)
        return stores
    
    def index(request):
        template = 'myhomechita/page.html'
        context = { 'stores': get_store,}
        return render(request, template, context)

    Part of the template
    {% if stores %}
        <div class="footer-col-2">
            <div class="col-name">Наши магазины</div>
            <ul class='stores'>
            {% for block in stores %}
                <li>
                {% for unit in block %}
                    {% if forloop.counter == 1 %}
                        <span>{{ unit.name }} - {{ unit.address }}</span>
                    {% else %}
                    <ul>
                        {% for phone in unit %}
                        <li>{{ phone.name }}: {{ phone.phone }}</li>
                        {% endfor %}
                    </ul>
                    {% endif %}
                {% endfor %}
                </li>
            {% endfor %}
            </ul>
        </div>
    {% endif %}
    Django Anonymous, Feb 4, 2020

  • 3 Answers
  • 0
    It is not very clear why you are forming the list, you can simply pass it to the queryset template, and do the rest of the work in the template, since you can loop through the queryset in the template. In the end, the template will look something like this:
    {% if stores_queryset %}
    <div class="footer-col-2">
    <div class="col-name">Наши магазины</div>
    <ul class='stores'>
    {% for store in stores_queryset %}
    <li>
    <span>{{ store.name }} - {{ store.address }}</span>
    <ul>
    {% for phone in store. phones_set %}
    <li>{{ phone.name }}: {{ phone.phone }}</li>
    {% endfor %}
    </ul>
    </li>
    {% endfor %}
    </ul>
    </div>
    {% endif %}


    About filtering phones with show = 1. You can do custom manager , and then only filtered phones will be in phones_set.

    Or, more simply, make a property in the Store model:
    class Store(models.Model):
    name = models.CharField(max_length=200)
    address = models.CharField(max_length=200)

    @property
    def showed_phones(self):
    return self.phones_set.filter(show=1)


    and then in the template, in the appropriate place, you need to use the {% for phone in store cycle. showed_phones%}
    Anonymous

  • 0
    'stores': Store.objects.all ()
    {% if stores %}
    <div class="footer-col-2">
    <div class="col-name">Наши магазины</div>
    <ul class='stores'>
    {% for store in stores_queryset %}
    <li>
    <span>{{ store.name }} - {{ store.address }}</span>
    <ul>
    {% for phone in store.phones_set %}
    <li>{{ phone.name }}: {{ phone.phone }}</li>
    {% endfor %}
    </ul>
    </li>
    {% endfor %}
    </ul>
    </div>
    {% endif %}


    Did this, but it doesn't output anything {% for store in stores_queryset%}
    Anonymous

  • 0
    In the store attribute of the Phones model add related_name:
    class Phones(models.Model):
    phone = models.CharField(max_length=50)
    store = models.ForeignKey(Store, related_name='phone_number')



    After that, you can reach your phone from the Store model like this:

    store = Store.objects.get(pk=1)
    phone_num = store.phone_number.phone



    You can also use the associated name in templates. Something like this ...

    {% if stores %}
    <div class="footer-col-2">
    <div class="col-name">Наши магазины</div>
    <ul class='stores'>
    {% for store in stores %}
    <li>


    <span>{{ store.name }} - {{ store.address }}</span>

    <ul>

    <li>{{ store.phone_number.name }}: {{ store.phone_number.phone }}</li>

    </ul>


    </li>
    {% endfor %}
    </ul>
    </div>
    {% endif %}
    Anastasia Herring

Your Answer
To place the code, please use CodePen or similar tool. Thanks you!