Ron Trunk
Ron Trunk

Reputation: 861

Can't reference related many-to-many object in Django

Here are my models:

class Vlan(models.Model):
    Name = models.CharField(max_length=20)
    VID = models.IntegerField(default=1)
    def __str__(self):
        return(str(self.VID) + ' ' + self.Name)


class Connection(models.Model):
    Description = models.CharField(max_length=80)
    Created = models.DateTimeField('Created Date')
    Change_Order = models.CharField(max_length=40)
    Implemented_by = models.CharField(max_length=80)
    def __str__(self):
        return(self.Description)

class Port(models.Model):
    Port_Number = models.IntegerField(default=1)
    Is_Pri = models.BooleanField(default=True)
    Switch = models.ForeignKey(Switch, on_delete=models.CASCADE)
    Connection = models.ForeignKey(Connection, null=True, blank=True, on_delete=models.SET_NULL)
    Vlans = models.ManyToManyField(Vlan,  blank=True)
    def __str__(self):
        return(str(self.Port_Number))

Each connection can have one or more ports, and each port can have one or more vlans (and a vlan can be on one or more ports).

I'm trying to create a list of dictionaries to render in a template. Each dictionary contains a list of port objects. Each port object contains a list of dictionaries with VLAN objects.

But I can't query a set of vlans, given a port object:

Here's the code:

def connlist(request, Conn_id):
    clist = Connection.objects.all()
    ctx_list = []
    ports =[]
    for c in clist:  # For each coonection
        plist = c.port_set.all()   # get a list of ports
        for p in plist:  # for each port
            vlist = p.vlan_set.all()  # get a set of vlans -- error!
            portd = {'port': p, 'vlist':vlist}
            ports.append(portd)
        ctx= {'conn': c.Description , 'ports': ports}
        ctx_list.append(ctx)
    template = loader.get_template('newcon/connlist.html')
    context = {'cons': ctx_list}
    return HttpResponse(template.render(context, request))

The line

    vlist = p.vlan_set.all()  # get a set of vlans -- error!

Gives an error:

'Port' object has no attribute 'vlan_set'

I'm not sure if I'm referencing vlans in the forward or backwards direction. I tried it both ways to no avail.

p.vlan.all()

p.vlan_set.all()

Any help would be greatly appreciated.

Upvotes: 2

Views: 26

Answers (2)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476659

You named your ManyToMany relation Vlans = models.ManyToManyField(Vlan, blank=True), so that means that you access the related vlans with:

p.Vlans.all()

Note: usually attributes of a class are written in lowercase_with_underscores, so you should rewrite it to vlans, not Vlans.

Upvotes: 1

Sam Creamer
Sam Creamer

Reputation: 5361

Since p is a Port instance, you don't need to call _set. You can simply write:

p.Vlans.all()

In this case, you're just calling Vlans as in the field in Port, not the Vlan model. Just as a heads up, by the way, the fields of your models should all be lowercase. Cheers!

Upvotes: 2

Related Questions