Новичок: Пытаясь понять, как приложения взаимодействуют в Django

голоса
28

Я только что закончил работать через учебники Джанго во второй раз, и я понимание вещей гораздо более четко в настоящее время. Тем не менее, я до сих пор неясно, как приложения внутри сайта взаимодействуют друг с другом.

Например, позволяет сказать, что я пишу приложение блог (довольно популярная активность, по-видимому). Публикаций и комментарии, как правило, идут рука об руку, и все же они достаточно того, что они должны быть встроены в отдельные приложения различны, как общая концепция развития Djano.

Рассмотрим следующий пример. На самом деле я бы не на самом деле написать комментарий приложение себя как хороший код, который уже существует в Интернете, но это для целей демонстрации / практики:

MySite / блог / models.py

from django.db import models

class post(models.Model):
    title = models.CharField(max_length=200)
    author = models.CharField(max_length=200)
    content = models.TextField()

MySite / комментарии / models.py

from django.db import models
from mysite.blog.models import post

class comment(models.Model):
    id = models.AutoField()
    post = models.ForeignKey(post)
    author = models.CharField(max_length=200)
    text = models.TextField()

Это то, что я написал выше, импортировать модель из другого приложения и установить его в качестве внешнего ключа, как Django приложение взаимодействует? Или есть другой / лучший способ для приложений, которые содержат сайт для взаимодействия?

Обновление
в соответствии с рекомендацией в одном ответе, я читаю документацию для contrib.contenttypes. Если я правильно читать это, я мог бы переписать мой пример комментарий приложение , как это:

from django.db import models  
from django.contrib.contenttypes.models import ContentType
from django.contrib.contentypes import generic

class comment(models.Model):  
    id = models.AutoField()  
    author = models.CharField(max_length=200)  
    text = models.TextField()  
    content_type = models.ForeignKey(ContentType)  
    content_object = generic.GenericForeignKey(content_type, id)  

Будет ли это правильно?

Задан 09/12/2008 в 18:25
источник пользователем
На других языках...                            


4 ответов

голоса
21

Посмотрите на Джанго встроенный в рамках ContentTypes :

django.contrib.contenttypes

Это позволяет разрабатывать приложения как автономные единицы. Это то , что разработчики Django использовали , чтобы Джанго встроенный комментарий рамки , чтобы прикрепить комментарий к любой модели в проекте.

Например, если у вас есть какой - нибудь объект контента , который вы хотите , чтобы «прикрепить» к другим содержанием объектов различных типов, например , что позволяет каждому пользователю оставить «любимой» звездой на своем блоге, образ, или профиль пользователя, вы можете создать Favoriteмодель с родовым соотношением области , как так:

from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Favorite(models.Model):
    user = models.ForeignKey(User)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

Таким образом , вы можете добавить Favoriteзвезду любого пользователя к любой модели в вашем проекте. Если вы хотите добавить доступ к API с помощью модели класса получателя вы можете добавить обратное родовое поле отношения на модели получателя (хотя это было бы «сцепная» две модели, которые вы сказали , что вы хотели бы избежать), или делать поиск через Favoriteмодель с content_typeи object_idэкземпляра получателя, смотрите официальные документы для примера.

Ответил 09/12/2008 в 19:01
источник пользователем

голоса
3

Там нет ничего плохого (имхо) с созданием некоторых приложений зависит от другого. В конце концов, приложения просто операции на множестве моделей. Вы просто должны всегда быть в курсе, какие приложения зависит от того, приложения (я думаю, вы могли бы назвать, что карты зависимостей).

Вы можете достичь слабосвязанности с каркасом ContentTypes. Это позволяет приложению быть поистине портативным / подключаемым пока еще интегрированы с другими приложениями.

Я написал комментарии приложение (да, я заново изобрел колесо), которые могут быть интегрированы в любое другое приложение, с помощью нескольких строк в шаблоне страницы, где комментарии должны быть вывешены (с помощью пользовательских тегов).

Допустим , вы хотите модель «нить» , чтобы быть подключаемыми в любой другой модели. Идея заключается в том , чтобы создать электронный общий внешний ключ (см Джанго документации по этому поводу ), и написать небольшую функцию , которая принимает любой объект и возвращает «нить» , соответствующую его (или создает один , если это необходимо), и написать собственный шаблон тег использует эту функциональность, например {% get_thread for arbitrary_object as thread %}. Все сообщения связаны с нитью, которая связана с объектом, который может быть любого типа.

Вы можете думать о «нити» объекта как своего рода прокси - сервер, так что вместо того , чтобы иметь должность быть связан с определенной «статьи» или «блоге», это просто связано с нитью, которая является абстрактным в том смысле , то , что это есть нить? Это просто набор сообщений. Нить затем позволяет себе быть связано с каким - либо объектом , независимо от его типа. (хотя это не более того, она могла бы провести дополнительную информацию , такую как разрешение / запрет Anon. , сообщения, закрытие / открытие комментарии на странице, и т.д ..)

РЕДАКТИРОВАТЬ

Вот как вы можете создать общий внешний ключ с каркасом типов контента:

from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType

class Thread( models.Model ):
    object_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    object = generic.GenericForeignKey('object_type', 'object_id')

Вы можете сделать его более «прозрачным», эксплуатируя неявный «общий» интерфейс, который Джанго принимает на себя все объекты реализации ..

    #inside the Thread class:
    def __unicode__(self):
        return unicode(self.object)
    def get_absolute_url(self):
        return self.object.get_absolute_url()
Ответил 09/12/2008 в 19:35
источник пользователем

голоса
3

«Это то, что я написал выше, импортировать модель из другого приложения и установить его в качестве внешнего ключа, как Django приложений постоянно взаимодействует?»

Ага. Работает на меня.

У нас есть около 10 приложений, которые одолжить назад и вперед между собой.

Это приводит к своему роду зависимость в нашем модульном тестировании сценария.

Похоже, что это.

  • "владение". У нас есть простое приложение собственности данных, который определяет некоторые основные понятия собственности, что другие приложения зависят. Есть несколько простых таблиц здесь.

  • "вещь". [Не реальное имя]. Наше дело приложение имеет элементы данных, принадлежащих различным группам пользователей. Есть на самом деле несколько сложных таблиц модели для этого приложения. Это зависит от «собственности».

  • «Таблица». [Не реальное имя]. Некоторые из наших пользователей создают довольно сложные модели off-line (возможно, с электронными таблицами) и загрузить результаты этого моделирования в «таблице». Это скопление довольно сложных таблиц. Это зависит от «собственности».

  • «Результат». [Не реальное имя]. Наши результаты основаны на вещах, которые имеют владельцев. Результаты основаны на вещах и таблиц, а также ответы на запросы клиентов. Это не слишком сложно, пожалуй, только два или три основные таблиц. Это зависит от «вещей» и «стол». Нет, он не полностью автономен. Тем не менее, она подвержена большему изменению, чем другие вещи, от которых она зависит. Вот почему это отдельно.

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

  • «Добро пожаловать». У нас есть «Добро пожаловать» приложение, которое представляет собой связку в основном статических страниц. Это не слишком много таблиц. Но это на его втором воплощении, так как первый был слишком сложным. Это полностью стоит особняком.

Единственная связь между зависимыми приложениями есть несколько имен таблиц. До тех пор, как мы храним эти таблицы (и ключи), мы можем изменить другие приложения, как мы видим, нужными.

Ответил 09/12/2008 в 19:06
источник пользователем

голоса
2

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

Как разделить проект

Я бы отделить приложение, если;

  • Я планирую разработать его resuable. (И попытаться слабосвязанности)
  • (Для крупных проектов) состоит из основной части проекта.

С другой стороны; имея много крошечных приложений (например, приложение с одной моделью и два точек зрения) трудно читать и поддерживать ИМХО.

Как приложения должны взаимодействовать

Это зависит от типа проекта и типа приложения снова. Например, если приложение неявным образом зависит от другого (т.е. не общий) импорт и использование ссылок из других приложений является приемлемым. В этом случае второе приложение может быть установлен отдельно, но первым нужно присутствие второго.

Если вы хотите , чтобы сделать приложение высоко многоразовым и родовым, такими как комментирование приложения, возможно , потребуется включить какой - то механизм установки. Может быть , некоторые новые параметры или дополнительные настройки URL, или специальная директива / метод на вашей модели ... django.contrib.adminэто хороший пример для этого.

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

Ответил 09/12/2008 в 18:45
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more