2011-02-04 2 views
2

Предположим, у вас есть две модели: Post и Category. Каждый Post имеет category_id.Двусторонний запрос в Django без круговой ссылки

Получение категории должности является простым: post.category. Что делать, если вы хотите получить все посты для определенной категории? Я полагаю, вы могли бы сделать

def posts(self): 
    return Post.filter(category__pk=self.id) 

Но что, если Post модель и Category модели находятся в отдельных файлах? Поскольку Post и Category теперь требуют друг друга, вы получите круговую ссылку.

Возможно, вы скажете, что решение: положить Post и Category в тот же файл. Но что, если ваше приложение имеет 50 разных моделей, многие из которых довольно большие, все в отдельных файлах? Должны ли вы объединить Post и Category в один файл и оставить все остальные отдельно? Должны ли вы объединить все 50 моделей в один гигантский файл?

Я надеюсь найти одну из двух вещей:

  1. Ответ на этот вопрос, который не включает комбинирование файлов
  2. Хорошую, логическую причины для группирования моделей в тот же файл с одним другой. Все мои модели связаны в какой-то степени, поэтому, где вы рисуете линию, насколько группируется? Если вы рисуете линию с помощью внешних ключей, все мои модели попадают в один и тот же файл.
+0

«вы получите круглую ссылку». Это предположение совершенно неверно. Почему вы говорите, что? –

+0

Я попробовал, и вот что случилось. –

+0

Пожалуйста, разместите код, который вы пробовали. У вас есть ошибка в коде. Все ваши «Может быть, вы говорите ...» до конца вопроса основываются на неправильных предположениях. Пожалуйста, разместите код и ошибку, которую вы действительно получаете. –

ответ

2

Вы можете ссылаться на модели по их имени (то есть на строку), а не на фактический объект. Являются ли они в отдельных приложениях? В этом случае вы можете обратиться к ним с помощью точечной нотации, как описано в documentation on ForeignKey:

#in mysite/categories/models.py 
class Category(models.Model): 
    ... 


#in mysite/posts/models.py 
class Post(models.Model): 
    category = models.ForeignKey('categories.Category') 

Вы также можете импортировать модель в функции, а не в верхней части файла. Я часто делать, чтобы избежать циклических ссылок:

def posts(self): 
    from posts.models import Post 
    return Post.filter(category__pk=self.id) 
+0

Ваша тактика с использованием импорта в работе. Благодаря! –

3

Для части 1. вашего вопроса:

Django автоматически устанавливает обратную связь для вас. на вашей категории у вас есть доступ к атрибуту post_set, который сам по себе Manager, так что вы можете сделать:

def posts(self): 
    return self.post_set.all() 

Отъезд the docs подробнее об этом.

Для части 2. У меня есть менее полный ответ ... Если у вас возникла необходимость разбить модели на столько файлов, у вас, вероятно, есть более фундаментальная проблема. Я бы сказал, вы должны подумать о том, чтобы разбить это огромное приложение на несколько более мелких.

Я думаю, что лучший совет, который я имел в плане сокращения размера моих приложений, - это «сделать одну вещь». Если ваше приложение не может быть описано в относительно короткой фразе, стоит подумать о том, как разбить его на несколько небольших приложений - каждый из которых «сделает одно».

Этот совет, конечно, довольно загружен. Требуется довольно много планирования, чтобы выяснить, как разрушить некоторые сложные задачи, а иногда и ретроспективный взгляд - единственный способ увидеть, откуда все вышло из-под контроля.И рефакторинг того размера, о котором вы говорите, может быть довольно сложным. (Если вы можете сказать, что я говорю по опыту!). Мой единственный совет в этом случае - сделать шаг за шагом. Попытайтесь сломать то, что выглядит как большие, связанные с приложениями проблемы, в маленькие, управляемые куски и делать их, когда сможете.

Чтобы решить вашу неотложную задачу, я предлагаю группировать ваши файлы в файлы локально или категорически. Это может привести вас в направлении рефакторинга этого приложения (что похоже на мамонт) в несколько небольших приложений. Я думаю, что это направление, в котором вы действительно должны руководствоваться этим.

Смежные вопросы