проблема модели Джанго с отношениями M2M и внешнего ключа - PullRequest
0 голосов
/ 06 мая 2011

У меня есть эта модель "рабочих мест" (показано ниже).

  • Существует связь M2M между хостами и местоположениями (для местоположения назначено несколько хостов).
  • У меня также есть класс часового пояса с отношением внешнего ключа, определенным между местоположением и часовым поясом (местоположению назначен часовой пояс)

Проблема, с которой я столкнулся, заключается в том, что я не могу откомментировать элемент 'colo' в классе Host из-за ссылки внешнего ключа на "Location". Класс Location определяется после класса Host. Но я не могу переместить определение Location выше класса Host из-за ссылки M2M для "hosts" в классе Location.

Я что-то упустил концептуально? Любая помощь будет принята с благодарностью!

Вот соответствующая часть моей модели:

class Timezone(models.Model):
    name = models.CharField(max_length=32, unique=True)
    def __unicode__(self):
        return "%s"%(self.name)

class Host(models.Model):
    name = models.CharField(max_length=32, unique=True)
#    colo = models.ForeignKey(Location)
    def __unicode__(self):
        return "%s"%(self.name)

class Location(models.Model):
    name = models.CharField(max_length=3, unique=True)
    hosts = models.ManyToManyField(Host, blank=True) #not required
    tz = models.ForeignKey(Timezone)
    def __unicode__(self):
        return "%s"%(self.name)

Ответы [ 3 ]

1 голос
/ 06 мая 2011

Между узлами и местоположениями имеется много-много взаимосвязей, однако вы хотите, чтобы узлы имели то же местоположение, которое вы на самом деле хотите, чтобы соотношение между узлами и местоположениями было одно-многим. Это объявляется с использованием models.ForeignKey, которое есть в вашем классе Host. Вам просто нужно изменить порядок кода, чтобы класс Host появился после класса Location, что позволит вам ссылаться на него. Также вы можете удалить отношения многие-многие.

class Timezone(models.Model):
    name = models.CharField(max_length=32, unique=True)
    def __unicode__(self):
        return "%s"%(self.name)    

class Location(models.Model):
    name = models.CharField(max_length=3, unique=True)
    tz = models.ForeignKey(Timezone)
    def __unicode__(self):
        return "%s"%(self.name)

class Host(models.Model):
    name = models.CharField(max_length=32, unique=True)
    colo = models.ForeignKey(Location)
    def __unicode__(self):
        return "%s"%(self.name)

Я не был уверен в лучшем способе сделать это, поэтому я просто напишу другой ответ. Мой первый ответ, в основном, позволил nnachefski создать модель, которую он определил в вопросе. Прочитав его комментарии, я понял, что ему на самом деле нужна модель, немного отличающаяся от той, которую он определил.

1 голос
/ 06 мая 2011

В принципе, вы не можете ссылаться на класс Location, пока он не был определен. Так что если вы меняете порядок классов Host и Location, это помогает. Тогда отношение многие ко многим относится к классу Host, который еще не определен. Но так как отношения между многими могут быть определены в любой таблице, просто переместите ее в класс Host. Вот модифицированный код:

class Timezone(models.Model):
    name = models.CharField(max_length=32, unique=True)
    def __unicode__(self):
        return "%s"%(self.name)

class Location(models.Model):
    name = models.CharField(max_length=3, unique=True)    
    tz = models.ForeignKey(Timezone)
    def __unicode__(self):
        return "%s"%(self.name)

class Host(models.Model):
    name = models.CharField(max_length=32, unique=True)
    colo = models.ForeignKey(Location, related_name='colocation')
    locations = models.ManyToManyField(Location, blank=True) #not required
    def __unicode__(self):
        return "%s"%(self.name)
0 голосов
/ 06 мая 2011

Поскольку у хоста будет только одно местоположение, вы можете удалить поле locations из модели хоста или удалить colo и изменить locations на location = models.ForeignKey(Location)

Чтобы получить все хосты из местоположения, вы можете сделать

location = Location.objects.get(pk=1)
hosts = location.host_set.all() #returns all hosts for the location

Вот ссылка на Django документы о обратных отношениях

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...