从<select>表单中选择对象 (HTML)

1 投票
1 回答
2511 浏览
提问于 2025-04-16 10:28

我正在学习如何使用 Google App Engine 和 Python(webapp)。

我之前是用 Java 的(这可能是我的问题!),在 Java 中,如果我把对象放到 Swing 的列表框里,它会自动调用对象的 toString() 方法来显示内容。当我选择其中一个对象时,它会返回这个对象本身,而不仅仅是 toString() 方法生成的字符串。

我有一个 Person 模型,用来保存个人的详细信息:

class Person(db.Model):
  '''represents a single person'''
  first = db.StringProperty()
  last  = db.StringProperty()
  address = db.StringProperty()
  city  = db.StringProperty()
  region = db.StringProperty()
  postal = db.StringProperty()
  country = db.StringProperty()
  phone = db.StringProperty()
  cell = db.StringProperty()
  email = db.StringProperty()
  comment = db.StringProperty(multiline=True)

还有一个 Reservation 模型,用来存储房间的信息,并记录哪个 Person 和这个预订有关:

class Reservation(db.Model):
    '''represents a single reservation'''
    room = db.StringProperty()
    start_day = db.IntegerProperty()
    start_month = db.IntegerProperty()
    start_year  = db.IntegerProperty()
    end_day = db.IntegerProperty()
    end_month = db.IntegerProperty()
    end_year = db.IntegerProperty()
    percent_discount = db.IntegerProperty()
    comment = db.StringProperty(multiline=True)
    client = #what would go here?

为了从用户那里获取预订信息,并把预订存入数据库,我有一个 HTML 表单,里面有各种字段,包括房间、到达日期、离开日期等等。其中有一个“客户列表”,用来获取已经在数据库中的 Person 列表:

    <select size="5" name="client_list"> 
    {% for person in clients %}
        <option>{{ person.first|escape }} {{ person.last|escape }}</option>
    {% endfor %}
</select>

这个功能可以显示名字,但我不知道如何把选中的“Person”或客户存入下面的 Reservation 代码中:

class Bookings(webapp.RequestHandler):
    '''Handles all of the bookings'''
    def post(self):
        '''adds a new booking into the db'''
        reservation = models.Reservation()

        reservation.room = self.request.get('room')
        reservation.start_day = int(self.request.get('start_day'))
        reservation.start_month = util.month_to_int(self.request.get('start_month'))
        reservation.start_year = int(self.request.get('start_year'))
        reservation.end_day = int(self.request.get('end_day'))
        reservation.end_month = util.month_to_int(self.request.get('end_month'))
        reservation.end_year = int(self.request.get('end_year'))
        reservation.percent_discount = int(self.request.get('percent_discount'))
        reservation.comment = self.request.get('comment')
        #This would get the clients first + last name, but not the object Person
        #reservation.client = self.request.get('client_list')

        reservation.put()
        self.redirect('/bookings')

我开始研究 Keys(特别是 db.Key.from_path),以及在 GAE 中每个 Person 都会生成一个唯一的 ID,但我仍然不知道如何从 HTML 中显示的名字获取到这个唯一 ID。

这看起来是可能的,甚至可能很简单,但经过两天的搜索我还是没有找到答案。如果需要我提供更多信息,请告诉我,这是我在 Stack Overflow 的第一次发帖!感谢任何建议。

1 个回答

5

根据文档的说明:

每个存储在数据存储中的模型实例都有一个唯一的键,用来表示这个对象。模型实例的key()方法会返回这个实例的Key对象。

所以你需要传递客户的key,而不是全名。请修改你的模板代码:

<select size="5" name="client"> 
  {% for person in clients %}
    <option value="{{ person.key }}">
      {{ person.first|escape }} {{ person.last|escape }}
    </option>
  {% endfor %}
</select>

要注意的是,<option>元素有自己的value属性。而我把<select>元素的名字从cleint_list改成client是因为它只能选择一个项目,而不能选择多个项目。

接下来,通过它的键来获取客户实例。根据文档:

应用程序可以使用get()函数来检索给定的Key的模型实例。

所以在你的应用程序中插入以下代码:

client_key = Key(self.request.get('client'))
client = Person.get(client_key)
if client is None:
    # in case the passed key isn't available
    return
reservation.client = client

撰写回答