2017-01-25 8 views
0

Я создаю простое приложение для рассылки новостей, которое собирает адреса электронной почты. У меня есть форма, которая отправляет значение электронной почты через ajax в мое приложение python, но я не могу, по моему мнению, выяснить, как узнать, существует ли почта. Следующий код в настоящее время функционирует, я просто не знаю, где/как добавить материал «проверить для существующей сущности».Предотвратить дублирование недвижимости в ndb datastore

import webapp2 
import json 

from google.appengine.ext import ndb 

class Email(ndb.Model): 
    email = ndb.StringProperty() 
    subscribed = ndb.BooleanProperty() 

    @staticmethod 
    def create(email): 
     ekey = ndb.Key("Email", email) 
     entity = Email.get_or_insert(ekey) 
     if entity.email: ### 
      # This email already exists 
      return None 
     entity.email = email 
     entity.subscribed = True 
     entity.put() 
     return entity 

class Subscribe(webapp2.RequestHandler): 
    def post(self): 
     add = Email.create(self.request.get('email')) 
     success = add is not None 
     self.response.headers['Content-Type'] = 'application/json' 
     obj = { 
      'success': success 
     } 
     self.response.out.write(json.dumps(obj)) 


app = webapp2.WSGIApplication([ 
    webapp2.Route(r'/newsletter/new', Subscribe), 
], debug=True) 

ответ

1

Обновленный ответ на основе комментария Дэн. Дэн, спасибо, что исправил меня. Дальнейшее обновление, чтобы ответить на обновленный вопрос.

Вы можете установить адрес электронной почты как идентификатор объекта электронной почты и использовать get_or_insert. Здесь хранилище электронной почты является избыточным, поскольку оно является идентификатором, а также свойством. Вероятно, вы можете избавиться от этой избыточности, проверив другое свойство на ### ниже.

class Email(ndb.Model): 
    email = ndb.StringProperty() 
    subscribed = ndb.BooleanProperty() 

    @staticmethod 
    def create(email): 
     ekey = ndb.Key("Email", email) 
     entity = Email.get_or_insert(ekey) 
     if entity.email: ### 
      # This email already exists 
      return None 
     entity.email = email 
     entity.subscribed = True 
     entity.put() 
     return entity 

class Subscribe(webapp2.RequestHandler): 
    def post(self): 
     add = Email.create(self.request.get('email')) 
     success = add is not None 
     self.response.headers['Content-Type'] = 'application/json' 
     obj = { 
      'success': success 
     } 
     self.response.out.write(json.dumps(obj)) 

Я не проверял код выше, поэтому могут быть ошибки, но это должно привести вас к правильному пути.

+2

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

+0

Но это транзакция в кросс-группе, поэтому это не должно работать? –

+1

«В транзакциях разрешены только предковые запросы». - не имеет значения, какая сделка –

1

Его хороший подход всегда создавать отдельный класс модели. Я создал отдельный класс модели и обновил метод post-подписчиков класса Subscribers, он вернет false, если адрес электронной почты существует, иначе он вернет true. Надеюсь, это решит вашу проблему.

class EmailModel(ndb.Model): 
     email = ndb.StringProperty() 
     subscribed = ndb.BooleanProperty() 

class Subscribe(webapp2.RequestHandler): 
     def post(self): 
     email = self.request.get('email') 
     entity = EmailModel.query(EmailModel.email == email).get() 
     if entity: 
      # Duplicate 
      check = False 
     else: 
      add = Email() 
      add.email = self.request.get('email') 
      add.subscribed = True 
      add.put() 
      check = True 
     if check: 
       self.response.headers['Content-Type'] = 'application/json' 
       obj = { 
       'success': True 
       } 
       self.response.out.write(json.dumps(obj)) 
     else: 
       self.response.headers['Content-Type'] = 'application/json' 
       obj = { 
       'success': False 
       } 
       self.response.out.write(json.dumps(obj)) 
+2

, следует отметить, что этот метод оставляет место для повторяющихся записей из-за возможной согласованности - запрос не может возвращать никаких результатов, даже если сущность существует (недавно созданная). –

+0

@DanCornilescu Я использую этот метод на разных сайтах и ​​не сталкивался с каким-либо дублированием. Можете ли вы предложить надежное решение, чтобы я мог обновить его на своих веб-сайтах? –