Django模型Meta选项unique_together用于appengine [英] Django model Meta option unique_together for appengine
问题描述
我在appengine上有一个应用,用于存储用户输入的一些数据字段。我想防止冗余条目,即如果所有字段都相同,则不应在数据库中输入数据。
I have an app on appengine that stores some data fields entered by user. I want to prevent redundant entries, i.e. if all fields are same, data should not be entered in database.
(可选)如果输入相同的数据,列count应该增加。
(Optional) If identical data is entered, value of a corresponding column "count" should be incremented.
我尝试使用Django Meta选项unique_together用于此目的,但似乎不起作用。相同的数据仍然存储在数据库中。请帮忙。这是我的代码:
I tried using Django Meta option unique_together for this purpose but it doesn't seem to work. Identical data is still being stored in database. Please help. Here is my code:
class Log(db.Model):
name = db.StringProperty()
location = db.StringProperty()
msg = db.StringProperty()
class Meta:
unique_together = (("name","location","msg"),)
推荐答案
有一些误会。
首先,您在代码中使用 datastore
,而不是django。 unique_together
或 Meta
选项 datastore
。
Datastore是appengine上的一个nosql服务。
Firstly, you are using datastore
in your code, not django. There is no unique_together
nor Meta
options for datastore
.
Datastore is a nosql service on appengine.
如果您要使数据存储区实体成为唯一的。最简单的方法是使用 key_name
。
key_name将是唯一的。稍后的实体将替换旧的,而它们具有相同的 key_name
。
If you want to make datastore entity to be unique. The easiest way is using key_name
.
key_name will be unique. The later entity will replace the old one while they have the same key_name
.
例如:
# key_name has length limit (500), hash it can make sure it won't exceed the limit
log = Log(
key_name=str(hash((name,location,msg))),
name=name,
location=location,
msg=msg
)
log.put()
# it will replace any exist log which has the same name, location, msg combination.
# and the item can be Retrieve via key_name directly.
log = Log.get(key_name)
EDIT2:
内置哈希
可能会在不同的机器中返回不同的值。所以最好使用hashlib。
built-in hash
may return different value in different machine. So it is better to use hashlib instead.
您可以通过多种方式定义您的 key_name
,只需确保事故不会发生冲突。
例如:
md5: http://docs.python。 org / 2 / library / md5.html
或者只是将所有字段附加在一起。 key_name = name +| +位置+| + msg
you can defined your key_name
in many ways, just make sure it won't collision in accident.
for example:
md5: http://docs.python.org/2/library/md5.html
or just append all field together. key_name=name + "|" + location + "|" + msg
了解更多信息:
https://developers.google.com/appengine/docs/python/datastore/entities#Retrieving_an_Entity
如果要在应用引擎上使用django,该模型应定义为:
If you want to use django on app engine, the model should be defined as:
from django.db import models
class Log(models.Model):
name = models.CharField(max_length=255)
location = models.StringProperty(max_length=255)
msg = models.StringProperty(max_length=255)
class Meta:
unique_together = (("name","location","msg"),)
EDIT3:
这是一个完整的例子,一个用于db,另一个用于ndb。
对于ndb来说,这很简单。对于数据库,这是一个有点困难。
Here is a complete example, one for db and the other for ndb. For ndb, it is quite simple. For db, it is a little bit hard.
from google.appengine.ext import db
from google.appengine.ext import ndb
import webapp2
class Log(db.Model):
name = db.StringProperty()
location = db.StringProperty()
msg = db.StringProperty()
count = db.IntegerProperty()
@classmethod
def key_name(cls, name, location, msg):
return name+"|"+location+"|"+msg
@classmethod
def get(cls, name, location, msg):
return db.get(db.Key.from_path(cls.__name__, cls.key_name(name, location, msg) ))
class nLog(ndb.Model):
name = ndb.StringProperty()
location = ndb.StringProperty()
msg = ndb.StringProperty()
count = ndb.IntegerProperty()
class Test1(webapp2.RequestHandler):
def get(self):
name='test_name'
location = 'test_location'
msg = 'test_msg'
Qkey_name= Log.key_name(name, location, msg)
log = Log(
key_name=Qkey_name,
name=name,
location=location,
msg=msg,
count=0
).put()
if Log.get(name, location, msg) is not None:
Qcount = Log.get(name, location, msg).count
else:
Qcount = 1
class Test2(webapp2.RequestHandler):
def get(self):
name='test_name'
location = 'test_location'
msg = 'test_msg'
Qkey_name = name + "|" + location + "|" + msg
log = nLog(
id=Qkey_name,
name=name,
location=location,
msg=msg,
count=0
).put()
if nLog.get_by_id(Qkey_name) is not None:
Qcount = nLog.get_by_id(Qkey_name).count
else:
Qcount = 1
app = webapp2.WSGIApplication([
(r'/1', Test1),
(r'/2', Test2)
], debug=True)
这篇关于Django模型Meta选项unique_together用于appengine的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!