How can I iterate the following data dictionary in Django

0

I have the following models in python:

class ModuleType(models.Model):
    name = models.CharField(max_length=150, unique=True)
    icon = models.CharField(max_length=100, unique=True)
    state = models.IntegerField(choices=state_choices, default=1)

    def __str__(self):
        return '%s' % (self.name)

class Module(models.Model):
    url = models.CharField(max_length=100,verbose_name='Url',unique=True)
    name = models.CharField(max_length=100,verbose_name='Nombre',unique=True)
    description = models.CharField(max_length=200, null=True,blank=True,verbose_name='Descripción')
    icon = models.CharField(max_length=100,verbose_name='Icono',null=True,blank=True,unique=True)
    image = models.ImageField(upload_to='modulo/%Y/%m/%d',verbose_name='Imagen',null=True,blank=True)
    type = models.ForeignKey(ModuleType,null=True,blank=True)
    dropdown = models.BooleanField(default=True,verbose_name='Despegable')
    state = models.IntegerField(choices=state_choices, default=1,verbose_name='Estado')

    def __str__(self):
        return '%s' % (self.name)

I have the following function in python:

def generate_treeview(id):
    data = {}
    modules = Module.objects.filter(groupmodule__groups_id=2, state=1, dropdown=True).exclude(type=None)
    for t in ModuleType.objects.filter(state=1,module__in=list(modules.values_list(flat=True))):
        data[t] = modules.filter(type=t)
    return data

It gives me the result if I print the following:

{<ModuleType: Seguridad>: <QuerySet [<Module: Tipos de Módulos>, <Module: Módulos>, <Module: Grupos>]>, <ModuleType: Publicidad>: <QuerySet [<Module: Portadas>]>}

How do I iterate it in a template? I did it in the following way but it works for me.

        {% for t in rmoduletreev %}
            <li class="treeview">
                <a href="#">
                    <i class="{{ t.icon }}" aria-hidden="true"></i> <span class="text-right-treeview">{{ t.name }}</span>
                    <span class="pull-right-container">
                  <i class="fa fa-angle-left pull-right"></i>
                </span>
                </a>
                <ul class="treeview-menu">
                     {% for mod in t.objects.all %}
                         <li><a href="{{ mod.url }}"><i class="{{ mod.icon }}"></i> {{ mod.name }}</a></li>
                       <p>{{ value }}</p>
                    {% endfor %}
                </ul>
            </li>
        {% endfor %}
    
asked by William Jair Davila Vargas 24.04.2018 в 23:56
source

2 answers

0

The first observation I make is about this line:

for t in ModuleType.objects.filter(state=1, module__in=list(modules.values_list(flat=True))):

In the module__in if you pass as argument list() that contains a queryset, then you are forcing Django to execute the query, so you have one more query, in reality, it has the same result, only that more optimal if you leave that line like this:

for t in ModuleType.objects.filter(state=1, module__in=modules.values_list(flat=True)):

Assuming that in your template, the variable rmoduletreev is the result of the function generate_treeview then you have to bear in mind that your data structure is the following:

data = {
    Objeto<ModuleType>: Array<Objeto<Module>>
}

So t (in your template) is an instance object of ModuleType , so, where is the error?

When you want to go through the QuerySet remember that you have a queryset already, and that queryset does not have the attribute objects , something happens with the variables in the Django templates, and that if they fail, then it will not throw error, always and when the error is inside the template, and obviously at t being an instance, you can not access its objects property either.

To solve the error, you should think about how python traverses dictionaries in a for loop, and it does it in the following way:

for x, y in diccionary:
   # donde x es el key
   # donde y es el value

That same form you can use in your template, staying like this:

{% for t, ti in rmoduletreev %}
     <li class="treeview">
         <a href="#">
             <i class="{{ t.icon }}" aria-hidden="true"></i> <span class="text-right-treeview">{{ t.name }}</span>
                <span class="pull-right-container">
              <i class="fa fa-angle-left pull-right"></i>
            </span>
            </a>
            <ul class="treeview-menu">
                 {% for mod in ti %}
                     <li><a href="{{ mod.url }}"><i class="{{ mod.icon }}"></i> {{ mod.name }}</a></li>
                   <p>{{ value }}</p>
                {% endfor %}
            </ul>
        </li>
    {% endfor %}

Tell me if it helps solve your problem

    
answered by 25.04.2018 / 01:06
source
0

should be worth to do the following in the template

    {% for t in rmoduletreev.moduletype %}
        .....
        .....
    {% endfor %}
    
answered by 25.04.2018 в 23:43