For example: I have an Article model with a repeated "title" property that stores translations in different languages of the original title:
class Article(ndb.Model):
title = ndb.StringProperty(repeated=True)
How can I store, besides the title property, the language code of the title, so I can get specific versions of the title, something like this:
en_title = article.title['en']
It is important to have the same property name since I don't know in what language the article title will be queried by.
You can use repeated structure property:
class Title(ndb.Model):
title = ndb.StringProperty()
lang = ndb.StringProperty()
class Article(ndb.Model):
titles = ndb.StructuredProperty(Title, repeated=True)
Are you querying on the titles or languages? If not, you can use PickleProperty or JsonProperty to store a dict.
Related
i am doing the finally degree work in Google App Engine, but i am having problems when i try this:
class Predicate(ndb.Model):
name = ndb.StringProperty()
parameters = ndb.JsonProperty()
class State(ndb.Model):
predicates = ndb.StructuredProperty(Predicate, repeated=True)
class Action(ndb.Model):
name = ndb.StringProperty()
parameters = ndb.StringProperty(repeated=True)
preconditions = ndb.StructuredProperty(Predicate, repeated=True)
predicatesToAdd = ndb.StructuredProperty(Predicate, repeated=True)
predicatesToDel = ndb.StructuredProperty(Predicate, repeated=True)
class Plan(ndb.Model):
plan = ndb.StructuredProperty(Predicate, repeated=True)
class Problem(ndb.Model):
initialState = ndb.StructuredProperty(Predicate)
goalState = ndb.StructuredProperty(Predicate)
actions = ndb.StructuredProperty(Action, repeated=True)
i get this error:
TypeError: This StructuredProperty cannot use repeated=True because its model class (Predicate) contains repeated properties (directly or indirectly).
StructuredProperty, if it contains repetitions, can not be replicated another StructuredProperty. But I need this structure models. How can i solve this?
And sorry for my bad english :(
I solved this problem using LocalStructuredProperty, but I think it will not work at all
The problem with your design is that ndb does not allow nested repeated properties. In other words, you cannot have a repeated structured property, which in turn has its own repeated property. If you remove the repeated=True from the parameters property, it will work.
You will need to re-think your design to work around this. One possible solution may be to use a JsonProperty for parameters, and store the list of strings as a JSON string. You won't be able to query them then of course, but it may work out depending on your requirements.
I want to get my object index as a "resource_uri" instead id
I take the usual way I make a model , views , serializers :
class User(BaseModel):
user = models.ForeignKey(settings.AUTH_USER_MODEL)
models.CharField()
class UserSerailizers(serializers.ModelSerializer):
class Meta:
model = User
fields = ('id','user','formatted_address')
classclass UserList(generics.ListCreateAPIView):
queryset = Image.objects.all()
serializer_class = UserSerializer
when i call < my_domain/user/ > I get this response
{
id:1,
name:'toto'
}
but I want to have an answer to this form:
{
'url': my_domain/user/1/
'name': 'toto'
}
Any thoughts?
If you want a hyperlink instead of a primary key in your model representations, you have to use either HyperlinkedModelSerializer or more generic Serializer along with HyperlinkedIdentityField and/or HyperlinkedRelatedField. The former is probably what you are looking for.
The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys.
See Django REST framework documentation for more details.
As already commented, you need to use the HyperlinkedModelSerializer as you've shown.
The lookup_field attribute should be inside the Meta class.
And the latest and this is a guess: You just have a ListView for your User model. In order to show the detail for the user, you need also the retrieve method. I would recommend you using the ModelViewset so it automatically implements all methods.
On the Google App Engine, I have a webapp2 model like this:
def Person(db.model):
first_name = db.StringProperty()
surname = db.StringProperty()
languages_spoken = db. ListProperty()
However, I'd like to have the languages_spoken list constrained to a list of options, say English, French, and Spanish, that can change as time goes on. With SQL this would be easy with person, language, and person_language tables (or similar) but I can't get my head round how to do it in this case, or even if it's possible. Any suggestions anyone?
I you are starting an appengine project, use the new NDB instead of the datastore. You can use properties with arguments like: choices and validator: https://developers.google.com/appengine/docs/python/ndb/properties
By using the NDB, you can have the following:
def Person(ndb.model):
first_name = db.StringProperty()
surname = db.StringProperty()
languages_spoken = db. ListProperty(choices=['English', 'French', 'Spanish'])
For more information about it, take a look at NDB Property Options.
However, notice that these options cannot change "on-the-fly". When a new option is supported by your application, you will need to add it in your model manually.
In the end I went with this, thanks to the pointers from the two other answers:
from google.appengine.ext import ndb
languages = ['English', 'French', 'Spanish']
def Person(ndb.model):
first_name = ndb.StringProperty()
surname = ndb.StringProperty()
languages_spoken = ndb.StringProperty(repeated=True, choices=languages)
Maybe my question is somehow unspecific, sorry for that. I'm learning python and app engine (webapp2) at the moment.
I have this class:
class Ice(db.Model):
"""Models an individual Guestbook entry with an author, content, and date."""
name = db.StringProperty()
description = db.StringProperty(multiline=True)
date = db.DateTimeProperty(auto_now_add=True)
def getTags(self):
return Tag.all().ancestor(self).fetch(10)
Tags are referenced via ancestor.
When I use a jinja-template i can call ice.getTags() foreach Ice.
Now i want to serialize my Ice-object to JSON and want to have all Tags that belong to the Ice-object in my JSON-Output.
This does serialisation for me:
It works okay, but it doesn't include the Tags.
I'm feeling, that i have to declare Tags as Ice-Attribute, but i don't know how.
class IceHandler(basehandler.BaseHandler):
def get(self):
ice_query = model.Ice.all().order('-date')
ices = ice_query.fetch(10)
self.response.write(json.encode(ices))
Thanks!
I'm designing a model for a posting system where an entry contains an image with or without a comment. An user can reply to it as either a comment or as an image entry as well.
As there can be more properties for ImageEntry, I came up with this design with Polymodel. Not sure if this is the best way to do this. Storage-wise, is CommentEntry less than ImageEntry?
Any suggestions would be great.
class Entry(polymodel.PolyModel):
comment = db.TextProperty()
reply_to = db.SelfReferenceProperty() # reference to the entry
created_at = properties.DateTimeProperty(auto_now_add=True)
updated_at = properties.DateTimeProperty(auto_now=True)
class CommentEntry(Entry):
created_by = db.ReferenceProperty(User, collection_name='comment_entries')
class ImageEntry(Entry):
created_by = db.ReferenceProperty(User, collection_name='image_entries')
image_url = db.LinkProperty(indexed=False)
slug = db.StringProperty(indexed=False)
this model will work fine, and yes, a CommentEntry will be smaller than an ImageEntry from the same user if the ImageEntry has an image URL and/or slug.
however, i'd make this much simpler by putting
created_by, image_url, and slug into Entry and getting rid
of CommentEntry and ImageEntry altogether. since
the app engine datastore is schemaless,
and properties are optional by default,
you'll only pay the cost of the image_url and slug properties when you fill them
in for image entries.