Взаимодействие ReferenceProperty с механизмом приложений Google - PullRequest
1 голос
/ 31 июля 2009

Я пытаюсь связать свои модели с помощью 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>

Ответы [ 4 ]

2 голосов
/ 31 июля 2009

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

Для модификаций используйте HTTP-глаголы, такие как POST (наиболее популярный, потому что все браузеры реализуют его правильно) или для специализированных операций PUT (для создания новых объектов) или DELETE (для удаления объектов). Я предполагаю, что вы будете использовать POST для поддержки различных браузеров.

Чтобы получить POST из браузера, вам потребуется либо Javascript wizardy, либо простая старая форма с методом = post - для простоты я приму последнее.

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

Если вы хотите избежать «богатых» фреймворков, вам придется вручную внедрять шаблоны для своих HTML-форм, направить их (с помощью какой-либо диспетчеризации URL-адресов, например, в app.yaml) на ваш обработчик, реализующий с помощью def post(self):, получить данные из запроса, проверить их, сформировать новый объект, поместить их, отобразить страницу подтверждения.

Какая часть или части процедуры вам неясны? Название вашего вопроса сфокусировано именно на ссылочных свойствах, но я не уверен, какую проблему они вам представляют, в частности - из текста вашего вопроса вы, кажется, находитесь на правильном пути.

Редактировать : ОП пояснил в комментарии, что его проблема в том, как сделать что-то вроде:

"<a href="/newtopic?id={{group.key.id}}" >New topic </a>" 

работа. Есть несколько способов сделать это. Если URL-адрес новой темы обслуживается статической формой, обработчик для post "action" этой формы может вернуться к этому id= через заголовок Referer: (печально известное, но нефиксированное неправильное написание), но это немного неуклюжий и хрупкий. Лучше, чтобы newtopic URI обслуживался обработчиком, чей def get получает id= из запроса и вставляет его в результирующий шаблон формы - например, в скрытое поле ввода. Шаблон этой формы должен содержать (среди других полей):

<INPUT TYPE=hidden NAME=thegroupid VALUE={{ theid }}> </INPUT>

поместите theid в контекст, с которым вы отображаете этот шаблон, и в запросе будет наконец получено def post действия, получающего форму.

1 голос
/ 28 октября 2009

Просто чтобы ответить на вопрос для других, как вы, наверное, поняли это:

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()
0 голосов
/ 31 июля 2009

Я не совсем уверен, какая у вас проблема. Все, что вы перечисляете, выглядит хорошо - 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.

0 голосов
/ 31 июля 2009

Спасибо за ответ.

Да, я в курсе о том, что ты получаешь пост. Класс, который я опубликовал, предназначался только для печати всех групп ().

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

Получение данных достаточно просто, и я использую:

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", а затем плюсы / минусы для каждой темы. Я понимаю, что немного расплывчато, но это потому, что я очень плохо знаком с реляционными базами данных и не совсем привык к терминологии.

...