开发者

making many to many relationships database in google app engine by python

Im trying to make 3 database; person, event and hobby. Each person selects hobbies from the list that is provided, which are in the hobby database. when a person creates a event, that person choose which hobby will be tagged to that event. From there event invitation will be send out to person who selected that hobby. And the event will be made using Google Calendar API....

im stuck on making this 3 database and trying to relate them using either relationalproperty or list property... looked around but not too good with programming so im kinda stuck... if anyone could help me that would be really appreciated.

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.SetA开发者_运维百科uthSubToken(
      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()

I have posted some of my code. I have edit event class and such after this but i guess its not that important in solving the database situation...

thanks in advance for any help or advice.


Your problem with creating a Person entity is that above (at p1) you're trying to assign a Hobby entity to Person.hobby which should be a list of Hobby keys (and probably be named hobbies)

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

Also, your Person model has no property event so Event.members will fail.

Other than these, using db.ListProperty() is the correct way to handle many to many relationships which carry no additional information.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜