создание базы данных отношений многие ко многим в google app engine с помощью python - PullRequest
1 голос
/ 24 августа 2011

Я пытаюсь сделать 3 базы данных; человек, событие и хобби. Каждый человек выбирает хобби из предоставленного списка, который находится в базе данных хобби. когда человек создает событие, этот человек выбирает, какое хобби будет привязано к этому событию. Оттуда приглашение на мероприятие будет отправлено человеку, который выбрал это хобби. И событие будет сделано с использованием Google Calendar API ....
я застрял на создании этой 3 базы данных и пытался связать их, используя свойство реляционной собственности или список ... осмотрелся, но не слишком хорошо разбирался в программировании, так что я вроде застрял ... если бы кто-нибудь мог мне помочь, это было бы очень признательно.

class Hobby(db.Model):
name = db.StringProperty()

@property
def members(self):
    return Person.all().filter('hobby', self.key())

h1 = Hobby(key_name ='key1', name = 'tennis')
h2 = Hobby(name = 'basketball')
h1.put()
h2.put()

class Person(db.Model):
name = db.StringProperty()
hobby = db.ListProperty(db.Key)


p1 = Person(name = 'tom', hobby = Hobby.get_by_key_name(['key1']))
p1.put()


class Event(db.Model):
title = db.StringProperty(required=True)
description = db.TextProperty()
time = db.DateTimeProperty()
location = db.TextProperty()
creator = db.UserProperty()
edit_link = db.TextProperty()
gcal_event_link = db.TextProperty()
gcal_event_xml = db.TextProperty()
hobby = db.ListProperty(db.Key)

@property
def members(self):
    return Person.all().filter('event', self.key())





class Attendee(db.Model):
  email = db.StringProperty()
  event = db.ReferenceProperty(Event)
  hobby = db.ReferenceProperty(Hobby)



class Greeting(db.Model):
  author = db.UserProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)





class BasePage(webapp.RequestHandler):
  title = ''

def write_page_header(self):
self.response.headers['Content-Type'] = 'text/html'
self.response.out.write('<html><head><title>%s</title>'
'<link href="static/invitations.css" rel="stylesheet" type="text/css"/>'
'</head><body><div id="main">' % (
    self.title,))
self.write_signin_links()



def write_signin_links(self):
if users.get_current_user():
  template_values = {
      'signed_in': True,
      'user_link': users.create_logout_url('/')}
else:
  template_values = {
      'signed_in': False,
      'user_link': users.create_login_url('/events')}
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'signin.html')
self.response.out.write(template.render(path, template_values))

def write_page_footer(self):
self.response.out.write('</div></body></html>')


class StartPage(BasePage):
  title = 'One Macnica'

  def get(self):
  self.write_page_header()
  template_values = {'sign_in': users.create_login_url('/events')}
  path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'start.html')
self.response.out.write(template.render(path, template_values))
self.write_page_footer()


class EventsPage(BasePage):
 title = 'One Macnica'

 def __init__(self):
# Create a Google Calendar client to talk to the Google Calendar service.
self.calendar_client = gdata.calendar.service.CalendarService()
# Modify the client to search for auth tokens in the datastore and use
# urlfetch instead of httplib to make HTTP requests to Google Calendar.
gdata.alt.appengine.run_on_appengine(self.calendar_client)

def get(self):
"""Displays the events the user has created or is invited to."""
self.write_page_header()

# Find all events which this user has created, and find events which this
# user has been invited to.
invited_events = []
owned_events = []
token_request_url = None

# Find an AuthSub token in the current URL if we arrived at this page from
# an AuthSub redirect.
auth_token = gdata.auth.extract_auth_sub_token_from_url(self.request.uri)
if auth_token:
  self.calendar_client.SetAuthSubToken(
      self.calendar_client.upgrade_to_session_token(auth_token))

# Check to see if the app has permission to write to the user's
# Google Calendar.
if not isinstance(self.calendar_client.token_store.find_token(
        'http://www.google.com/calendar/feeds/'),
    gdata.auth.AuthSubToken):
  token_request_url = gdata.auth.generate_auth_sub_url(self.request.uri,
     ('http://www.google.com/calendar/feeds/',))


query_time = self.request.get('start_time')
# TODO handle times provided in the URL.
if not query_time:
  query_time = datetime.datetime.now()

# Find the events which were created by this user, and those which the user
# is invited to.
if users.get_current_user():
  owned_query = Event.gql('WHERE creator = :1 ORDER BY time',
      users.get_current_user())
  owned_events = owned_query.fetch(5)

  invited_query = Attendee.gql('WHERE email = :1',
      users.get_current_user().email())
  for invitation in invited_query.fetch(5):
    try:
      invited_events.append(invitation.event)
    except db.Error, message:
      if message[0] == 'ReferenceProperty failed to be resolved':
        # The invitee has an invitation to an event which no longer exists.
        pass
      else:
        raise

template_values = {
    'token_request_url': token_request_url,
    'owned_events': owned_events,
    'invited_events': invited_events,
     }



# Display the events.
path = os.path.join(os.path.dirname(__file__), 'templates')
path = os.path.join(path, 'events.html')
self.response.out.write(template.render(path, template_values))
self.write_page_footer()


def post(self):
"""Adds an event to Google Calendar."""
event_id = self.request.get('event_id')

# Fetch the event from the datastore and make sure that the current user
# is an owner since only event owners are allowed to create a calendar
# event.
event = Event.get_by_id(long(event_id))



if users.get_current_user() == event.creator:
  # Create a new Google Calendar event.
  event_entry = gdata.calendar.CalendarEventEntry()
  event_entry.title = atom.Title(text=event.title)
  event_entry.content = atom.Content(text=event.description)
  if start_time is None:
    start_time = '%s.000Z' % event.time.isoformat()
    end_time = '%s.000Z' % event.time.isoformat(time.time()+3600)
  event_entry.when.append(gdata.calendar.When(start_time=start_time, end_time=end_time))
  event_entry.where.append(
      gdata.calendar.Where(value_string=event.location))
  # Add a who element for each attendee.
  attendee_list = event.attendee_set
  if attendee_list:
    for attendee in attendee_list:
      new_attendee = gdata.calendar.Who()
      new_attendee.email = attendee.email
      event_entry.who.append(new_attendee)

 #Adding hobby for each attendee
"""hobby_list = event.hobby_set
  if hobby_list:
    for hobby in hobby_list:
        new_hobby = gdata.calendar.ExtendedProperty()
        new_hobby.name = hobby.name
        event_entry.extended_property.append(new_hobby)
        """

 # Hobby to which a person belongs:
p = db.get(person_key)
hobby = db.get(p.hobby) #batch get using list of keys
for hobby in hobby:
        new_hobby = gdata.calendar.ExtendedProperty()
        new_hobby = hobby.name
        event_entry.extended_property.append(new_hobby)


#Person that belong to a hobby:
h = db.get(hobby_key)
for person in h.members:
        new_person = gdata.calendar.Who()
        new_person.name = person.name
        event_entry.who.append(new_person)



# Event to which a person belongs:
p = db.get(person_key)
event = db.get(p.event)
for event in event:
        new_event = gdata.calendar.ExtendedProperty()
        new_event = event.title
        event_entry.extended_property.append(new_event)

# Person that belong to a event:
e = db.get(event_key)
for person in e.members:
        new_person = gdata.calendar.Who()
        new_person.name = person.name
        event_entry.who.append(new_person)



  # Send the event information to Google Calendar and receive a
  # Google Calendar event.
try:
    cal_event = self.calendar_client.InsertEvent(event_entry,
        'http://www.google.com/calendar/feeds/default/private/full')
    edit_link = cal_event.GetEditLink()
    if edit_link and edit_link.href:
      # Add the edit link to the Calendar event to use for making changes.
      event.edit_link = edit_link.href
    alternate_link = cal_event.GetHtmlLink()
    if alternate_link and alternate_link.href:
      # Add a link to the event in the Google Calendar HTML web UI.
      event.gcal_event_link = alternate_link.href
      event.gcal_event_xml = str(cal_event)
    event.put()
  # If adding the event to Google Calendar failed due to a bad auth token,
  # remove the user's auth tokens from the datastore so that they can
  # request a new one.
except gdata.service.RequestError, request_exception:
    request_error = request_exception[0]
    if request_error['status'] == 401 or request_error['status'] == 403:
      gdata.alt.appengine.save_auth_tokens({})
    # If the request failure was not due to a bad auth token, reraise the
    # exception for handling elsewhere.
    else:
      raise
else:
  self.response.out.write('I\'m sorry, you don\'t have permission to add'
                          ' this event to Google Calendar.')

# Display the list of events also as if this were a get.
self.get()

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

Заранее спасибо за любую помощь или совет.

1 Ответ

0 голосов
/ 26 августа 2011

Ваша проблема с созданием сущности Person заключается в том, что выше (на p1) вы пытаетесь присвоить Hobby сущность для Person.hobby, которая должна быть списком ключей Хобби (и, вероятно, быть названными хобби)

h = Hobby(name='basketball')
h_key = h.put() # or after h.put(), h.key()
p = Person(name='tom', hobbies=[h_key])
p.put()

Кроме того, ваша Person модель не имеет свойства event, поэтому Event.members завершится ошибкой.

Кроме них, использование db.ListProperty() является правильным способом обработки множества отношений, которые не несут никакой дополнительной информации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...