我试图建立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()
我发布了一些代码。我之后编辑了事件类等,但我认为它在解决数据库情况时并不重要......
提前感谢任何帮助或建议。
答案 0 :(得分:0)
创建Person
实体的问题在于上面(在第1页)您尝试将Hobby
实体分配给Person.hobby
,该实体应该是一个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()
是处理多对多关系的正确方法,这些关系不包含其他信息。