Вопрос по model, google-app-engine, python, django-templates, django-models – Взаимодействие ReferenceProperty с механизмом приложений Google
Я пытаюсь связать свои модели с помощью ReferenceProperty, но мне не повезло. У меня есть 3 уровня: группа, тема, затем плюсы и минусы. Как и в группе домов много тем, и внутри каждой темы может быть много плюсов и минусов.
Я могу хранить новые группы хорошо, но у меня нет никакой идеи, как хранить темы под этими группами. Я хочу создать ссылку со страницы со ссылкой "Новая тема" под каждой группой, которая переводит их в простую форму (1 поле на данный момент). Очевидно, что URL должен иметь какую-то ссылку на идентификатор группы или что-то в этом роде.
Вот мои модели:
class Groups(db.Model):
group_user = db.UserProperty()
group_name = db.StringProperty(multiline=True)
group_date = db.DateTimeProperty(auto_now_add=True)
class Topics(db.Model):
topic_user = db.UserProperty()
topic_name = db.StringProperty(multiline=True)
topic_date = db.DateTimeProperty(auto_now_add=True)
topic_group = db.ReferenceProperty(Groups, collection_name='topics')
class Pro(db.Model):
pro_user = db.UserProperty()
pro_content = db.StringProperty(multiline=True)
pro_date = db.IntegerProperty(default=0)
pro_topic = db.ReferenceProperty(Topics, collection_name='pros')
class Con(db.Model):
con_user = db.UserProperty()
con_content = db.StringProperty(multiline=True)
con_date = db.IntegerProperty(default=0)
con_topic = db.ReferenceProperty(Topics, collection_name='cons')
И одна функция для реальной страницы, я хочу показать список групп, а затем под их темами:
class Summary(webapp.RequestHandler):
def get(self):
groups_query = Groups.all()
groups = groups_query.fetch(1000)
template_values = {
'groups': groups,
}
path = os.path.join(os.path.dirname(__file__), 'summary.html')
self.response.out.write(template.render(path, template_values))
И, наконец, HTML:
<html>
<body>
<a href="/newgroup">New Group</a>
<br>
{% for group in groups %}
<font size="24">{{ group.group_name|escape }}</font><br> by <b>{{ group.group_user }}</b> at <b>{{ group.group_date }}</b> {{ group.raw_id }}
<br>
<a href="/newtopic?id={{group.key.id}}" >New topice </a>
<br>
<blockquote>
{{ topics.topics_name }}
</blockquote>
{% endfor %}
</body>
</html>
что имеет побочные эффекты, такие как изменение магазина (например, путем создания нового объекта), должноNOT быть HTTPGET
- GET должен, по существу, только "читать" операции. Это не педантичность, это ключевой бит семантики HTTP - браузеры, кеши, прокси и т. Д. Могут работать с GET как операции только для чтения (например, путем кэширования результатов и не передачи запроса на сервер, если они могут удовлетворить это из кеша).
Для изменений используйте HTTP-глаголы, такие как POST (наиболее популярный, потому что все браузеры реализуют его правильно) или для специализированных операций PUT (для создания новых объектов) или DELETE (для удаления объектов). Я предполагаю, что вы будете использовать POST для поддержки различных браузеров.
Чтобы получить POST из браузера, вам понадобится либо Javascript wizardy, либо простая старая форма с методом = post - я приму последнее для простоты.
Если вы используете Django 1.0 (который сейчас поддерживает механизм приложений), у него есть свои собственные механизмы для создания, проверки и принятия форм на основе моделей. Другие фреймворки имеют свои аналогичные расширенные слои.
Если вы хотите избежать & quot; богатого & quot; фреймворки, которые вам придется вручную создавать шаблоны для ваших HTML-форм, направлять их (через какую-то диспетчеризацию URL, например, в app.yaml) на ваш обработчик, реализующий с помощьюdef post(self):
получить данные из запроса, проверить их, сформировать новый объект, поместить их, отобразить страницу подтверждения.
Какая часть или части процедуры вам неясны? Заголовок вашего вопроса сфокусирован конкретно на ссылочных свойствах, но я не уверен, какую проблему они вам представляют, в частности - из текста вашего вопроса вы, кажется, находитесь на правильном пути.
Edit: ОП теперь пояснил в комментарии, что его проблема в том, как сделать что-то вроде:
"<a href="/newtopic?id={{group.key.id}}" >New topic </a>"
Работа. Существует более одного способа сделать это. Если URL-адрес новой темы обслуживается статической формой, обработчик для сообщения "action" quot; этой формы может вернуться к этомуid=
черезReferer:
заголовок (печально известное, но не исправляемое неправильное написание), но это немного неуклюже и хрупко. Лучше, чтобы ньютопический URI обслуживался обработчиком, чейdef get
получаетid=
из запроса и вставляет его в результирующий шаблон формы - например, в скрытое поле ввода. Шаблон этой формы должен содержать (среди других полей):
<INPUT TYPE=hidden NAME=thegroupid VALUE={{ theid }}> </INPUT>
положилtheid
в контексте, с которым вы отображаете этот шаблон, и это будет в запросе, чтоdef post
от действия, получающего форму, наконец получает.
<a href=
я хотел предупредить об этом (теперь ОП уточнил, что это правильно приводит к опубликованной форме). У вас тоже были проблемы с пониманием вопроса (хотя, по крайней мере, ваш ответ вызвал некоторые пояснения, так что кажется), так почему же нужно понизить ответ с широким спектром, который пытается удостовериться, что все основания затронуты перед лицом неопределенности?
newtopic.topic_group = grp.key()
это то, что должно произойти до того, какnewtopic.put()
хотя ты можешь просто сделатьnewtopic.topic_group = grp
и он возьмет ключ от вашего имени. Поэтому лучше всего передать ключ напрямую (& quot; ключ с кодировкой строки - это непрозрачное значение, использующее символы, безопасные для включения в URL-адреса ... можно преобразовать обратно в объект Key, передав его конструктору Key (закодированному аргумент). "согласноcode.google.com/appengine/docs/python/datastore/keyclass.html
как вы, наверное, поняли это:
class NewTopic(webapp.RequestHandler): def get(self): groupId = self.request.get('group') # either get the actual group object from the DB and initialize topic with topic_group=object as in 'Nick Johnson's answer, or do as follows topic = Topic() topic.name = self.request.get("topicname") topic.reference = groupId topic.put()
Да, я знаю о том, чтобы получить против поста. Класс, который я разместил, предназначался только для печати всех групп ().
Проблема, с которой я столкнулся, заключается в том, что я не уверен, как использовать модели для иерархического хранения данных с группами & gt; Темы & gt; За и против.
Сбор данных достаточно прост, и я использую:
class NewGroupSubmit(webapp.RequestHandler):
def post(self):
group = Groups()
if users.get_current_user():
group.group_user = users.get_current_user()
group.group_name = self.request.get('groupname')
group.put()
self.redirect('/summary')
Мне нужна другая функция, чтобы добавить новую тему, которая хранит ее в этой группе. Допустим, группа - это «Автомобили». например; темами могут быть «Ferrari», «Porsche», «BMW», а затем плюсы / минусы для каждой темы. Я понимаю, что я немного расплывчат, но это потому, что я очень плохо знаком с реляционными базами данных и не совсем привык к терминологии.
с какой проблемой вы столкнулись. Все, что вы перечисляете, выглядит хорошо - ReferenceProperties настроены в соответствии с тем, что вы ожидаете от вашей подписки. Единственная проблема, которую я вижу, состоит в том, что в вашем шаблоне вы ссылаетесь на переменную "themes", которая нигде не определена, и вы нигде не просматриваете темы для группы. Вы можете сделать это так:
<html>
<body>
<a href="/newgroup">New Group</a>
<br>
{% for group in groups %}
<font size="24">{{ group.group_name|escape }}</font><br> by <b>{{ group.group_user }}</b> at <b>{{ group.group_date }}</b> {{ group.raw_id }}
<br>
<a href="/newtopic?id={{group.key.id}}" >New topice </a>
<br>
Topics:
<ul>
{% for topic in group.topics %}
<li>{{topic.topic_name}}</li>
{% endfor %}
</ul>
{% endfor %}
</body>
</html>
Чтобы создать новую тему, просто используйте конструктор, передавая необходимые аргументы:
mytopic = Topic(topic_name="foo", topic_group=somegroup)
Здесь somegroup должен быть либо объектом Group, либо ключом для объекта Group.