views:

450

answers:

2

Hi,

I have two simple models in models.py: Service and Host. Host.services has a m2m relationship with Service. In other words, a host has several services and one service can reside on multiple hosts; a basic m2m.

models.py

class Service(models.Model):

    servicename = models.CharField(max_length=50)

    def __unicode__(self):
            return self.servicename

    class Admin:
            pass

class Host(models.Model):

    #...
    hostname = models.CharField(max_length=200)
    services = models.ManyToManyField(Service)
    #...

    def service(self):
            return "\n".join([s.servicename for s in self.services.all()])


    def __unicode__(self):
            return self.hostname

    class Admin:
            pass

How do i get a one-to-many output in the admin interface, with the class 'Service' as basis (a reverse many-to-many?).

Do i need to use '_set.all()' ?

A: 

Use related_name on the services:

services = models.ManyToManyField(Service, related_name='hosts')

and then do

service.hosts.all()

to get the hosts for a service.

Vinay Sajip
Do i put this:service.hosts.all()within 'class Host'?
Bas van der Zon
No. If you have a `Host` instance `host` and you want to find its services, you'd do `host.services.all()`. Similarly, if you have a `Service` instance `service` and you want to find its hosts, you do `service.hosts.all()`. Here, `service` is a particular `Service` instance you're interested in at any particular time.
Vinay Sajip
This would typically go into code for a view (e.g. to display the hosts for a service when viewing the service information)
Vinay Sajip
A: 

This seems to do the trick:

class Service(models.Model):
    servicename = models.CharField(max_length=50)

    def hostname(self):
            return "\n".join([s.hostname for s in self.hosts_services.all()])

    def __unicode__(self):
            return self.servicename

class Host(models.Model):
    #...
    services = models.ManyToManyField(Service, related_name='hosts_services')
    #...
Bas van der Zon