Структура проекту для Google App Engine


119

Я запустив заявку в Google App Engine відразу, коли з’явився, щоб грати з технологіями та працювати над проектом для домашніх тварин, про який я довго думав, але ніколи не замислювався над тим, щоб почати. Результат - BowlSK . Однак, оскільки вона зростала та додавались особливості, стало важко організувати речі - головним чином через те, що це мій перший проект пітона, і я нічого про це не знав, поки не почав працювати.

Що я маю:

  • Основний рівень містить:
    • всі файли .py (не знав, як змусити працювати пакети)
    • всі шаблони .html для сторінок основного рівня
  • Підкаталоги:
    • окремі папки для css, зображень, js тощо
    • папки, що містять шаблони .html для URL-адрес типу subdirecty

Приклад:
http://www.bowlsk.com/ відображає на HomePage (пакет за замовчуванням), шаблон на "index.html"
http://www.bowlsk.com/games/view-series.html?series=7130 карта на ViewSeriesPage (знову пакет за замовчуванням), шаблон у "games / view-series.html"

Це противно. Як здійснити реструктуризацію? У мене було 2 ідеї:

  • Основна папка, що містить: appdef, індекси, main.py?

    • Підпапка для коду. Чи повинен це бути моїм першим пакетом?
    • Підпапка для шаблонів. Герархія папок відповідатиме пакетній герархії
    • Індивідуальні підпапки для css, зображень, js тощо
  • Головна папка, що містить appdef, індекси, main.py?

    • Підпапка для коду + шаблони. Таким чином, у мене є клас обробника поруч із шаблоном, тому що на цьому етапі я додаю безліч функцій, тож модифікації однієї середньої модифікації мають інші. Знову ж, чи потрібно, щоб ця назва папки була першою назвою пакета для моїх класів? Я хотів би, щоб папка була "src", але я не хочу, щоб мої заняття були "src.WeverPage"

Чи є найкраща практика? З Django 1.0 на горизонті, чи можу я щось зараз зробити, щоб покращити свою здатність інтегруватися з ним, коли він стає офіційним двигуном шаблону GAE? Я б просто почав пробувати ці речі, і побачив, що здається кращим, але підтримка рефакторингу pyDev, здається, не дуже добре справляється з переміщеннями пакетів, тому, швидше за все, це буде нетривіальним завданням змусити все це знову працювати.

Відповіді:


104

По-перше, я б запропонував вам поглянути на " Швидкий розвиток за допомогою Python, Django та Google App Engine "

GvR описує загальний / стандартний макет проекту на сторінці 10 своєї слайд-презентації .

Тут я опублікую трохи змінену версію макета / структури з цієї сторінки. Я дуже дотримуюся цієї схеми сам. Ви також згадали, що у вас виникли проблеми з пакетами. Просто переконайтесь, що кожна з ваших підпапок має файл __init__.py. Це нормально, якщо його порожньо.

Файли котла

  • Вони майже не відрізняються між проектами
  • app.yaml: направляйте всі нестатичні запити на main.py
  • main.py: ініціалізуйте додаток та надішліть йому всі запити

Макет проекту

  • static / *: статичні файли; обслуговується безпосередньо App Engine
  • myapp / *. py: специфічний для програми python-код
    • views.py, models.py, testing.py, __init__.py та багато іншого
  • шаблони / *. html: шаблони (або myapp / шаблони / *. html)

Ось кілька прикладів коду, які також можуть допомогти:

main.py

import wsgiref.handlers

from google.appengine.ext import webapp
from myapp.views import *

application = webapp.WSGIApplication([
  ('/', IndexHandler),
  ('/foo', FooHandler)
], debug=True)

def main():
  wsgiref.handlers.CGIHandler().run(application)

myapp / views.py

import os
import datetime
import logging
import time

from google.appengine.api import urlfetch
from google.appengine.ext.webapp import template
from google.appengine.api import users
from google.appengine.ext import webapp
from models import *

class IndexHandler(webapp.RequestHandler):
  def get(self):
    date = "foo"
    # Do some processing        
    template_values = {'data': data }
    path = os.path.join(os.path.dirname(__file__) + '/../templates/', 'main.html')
    self.response.out.write(template.render(path, template_values))

class FooHandler(webapp.RequestHandler):
  def get(self):
    #logging.debug("start of handler")

myapp / models.py

from google.appengine.ext import db

class SampleModel(db.Model):

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

Макет проекту

  • статичні /: статичні файли; обслуговується безпосередньо App Engine
    • js / *. js
    • зображення / *. gif | png | jpg
    • css / *. css
  • myapp /: структура додатків
    • моделей / *. py
    • вид / *. py
    • тести / *. py
    • шаблони / *. html: шаблони

2
Як тільки ви отримаєте 20 або 30 переглядів і пару "поглядів", які просто обробляють пости та потім переспрямовують, ви розбиваєте їх на окремі файли? Можливо, в myapp / views / view1.py, myapp / views / view2.py? Або це лише мій фон Java / C #, що відображається?
Кріс Марасті-Георг

1
Я відредагував свою публікацію для вирішення великих проектів. Я сподіваюся, що це допомагає. Майте на увазі, що в деяких випадках це буде вирок суду.
fuentesjr

1
У мене схожий макет, але використовуйте "app" замість "myapp".
Олександр Коєвніков

Чи може хтось надати робочий приклад для такої верстки проекту? Я не знайшов нічого підходящого.
herrherr

16

Моя звичайна компоновка виглядає приблизно так:

  • app.yaml
  • index.yaml
  • request.py - містить базовий додаток WSGI
  • ліб
    • __init__.py - загальна функціональність, включаючи базовий клас обробника запитів
  • контролери - містить усі обробники. request.yaml імпортує ці.
  • шаблони
    • всі шаблони джанго, якими користуються контролери
  • модель
    • всі класи моделей зберігання даних
  • статичний
    • статичні файли (css, зображення тощо). Зібрано в / статично за допомогою app.yaml

Я можу навести приклади того, як виглядають контролери app.yaml, request.py, lib / init .py та зразок, якщо це не зрозуміло.


5
Привіт Нік, будь ласка, зроби це! Мені також потрібно порівняти різні рішення :) Дякую!
Хоанг Фам

2
Привіт, я також хотів би побачити кілька прикладів, якщо це можливо. Дякую.

11

Сьогодні я реалізував котло для двигуна додатка google і перевірив його на github. Це узгоджується з описаними вище Ніком Джонсоном (який раніше працював у Google).

Перейдіть за цим посиланням gae-kotplate


1
Чи можете ви трохи розширити цю відповідь? Посилання github - це все добре і добре для підтвердження вашої відповіді, але вам слід принаймні спробувати її трохи ввести.
Shog9

1
README.md у корені gae-kotplate пояснює все це. github.com/droot/gae-boilerplate/blob/master/README.md
Ед Рандалл

7

Я думаю, що перший варіант вважається найкращою практикою. І зробіть папку коду своїм першим пакетом. Проект Рітвельда, розроблений Гвідо ван Россум, є дуже хорошою моделлю, з якої слід вчитися. Погляньте на це: http://code.google.com/p/rietveld

Що стосується Django 1.0, я пропоную вам почати використовувати код магістралі Django замість GAE, вбудованого в порт django. Знову подивіться, як це робиться в Рітвельді.


Яка найкраща причина використовувати Django? Я використовую WebApp, і він мені добре допомагає. Крім того, я сподіваюся, що Google найближчим часом запропонує кращу інтеграцію цих двох. Який мінус у використанні вбудованого в порт Django?
jamtoday

3

Мені подобається webpy, тому я прийняв його як шаблонну структуру в Google App Engine.
Мої папки пакунків зазвичай організовані так:

app.yaml
application.py
index.yaml
/app
   /config
   /controllers
   /db
   /lib
   /models
   /static
        /docs
        /images
        /javascripts
        /stylesheets
   test/
   utility/
   views/

Ось приклад.


1

Я не зовсім в курсі останніх найкращих практик, і так далі, коли мова заходить про макет коду, але коли я зробив своє перше додаток GAE, я використав щось у вашому другому варіанті, де код і шаблони знаходяться поруч із іншими.

Причин для цього було дві - одна, вона зберігала код і шаблон поблизу, а по-друге, я мав структуру каталогів структури, що імітує структуру веб-сайту - і це (для мене) трохи простіше запам'ятати, де все було.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.