escalant3 / ember-data-tastypie-adapter Goto Github PK
View Code? Open in Web Editor NEWAn adapter to connect django applications powered by django-tastypie with ember.js apps
License: MIT License
An adapter to connect django applications powered by django-tastypie with ember.js apps
License: MIT License
I am not sure if Ember-CLI is supported however it used to work prior to the new export syntax from this commit: 30ac3cc
Perhaps I am doing it wrong after that update?
Previously I had added to the brocfile.js:
app.import('vendor/ember-data-tastypie-adapter/packages/ember-data-tastypie-adapter/lib/tastypie_adapter.js');
app.import('vendor/ember-data-tastypie-adapter/packages/ember-data-tastypie-adapter/lib/tastypie_serializer.js');
and then called them in an app/adapters/application.js like so:
import DS from "ember-data";
export default DS.DjangoTastypieAdapter.extend({
namespace: 'api/v1',
});
With this configuration I new get:
Uncaught SyntaxError: Unexpected reserved word
which i believe to be due to the import statement. Same thing happens if i switch to using main.js instead of tastypie_adapter.js and tastypie_serializer.js in my brocfile.js.
I have tried using what I believe is the ES6 syntax (shown below), however it still fails:
app.import('vendor/ember-data-tastypie-adapter/packages/ember-data-tastypie-adapter/lib/tastypie_main.js', {
exports: {
'tastypie_adapter': [
'DjangoTastypieAdapter',
'DjangoTastypieSerializer',
]
}
});
or:
app.import('vendor/ember-data-tastypie-adapter/packages/ember-data-tastypie-adapter/lib/tastypie_adapter.js', {
exports: {
'tastypie_adapter': [
'default',
]
}
});
app.import('vendor/ember-data-tastypie-adapter/packages/ember-data-tastypie-adapter/lib/tastypie_serializer.js', {
exports: {
'tastypie_serializer': [
'default',
]
}
});
I also tried to reference these manually using .jshintrc by adding statements to the predef like so:
"DjangoTastypieAdapter": true,
"DjangoTastypieSerializer": true,
This is no longer working. I anticipate this is due to having to new build using broccoli manually? That also fails when i attempt to build the module from my vendor folder.
If that is the case, perhaps we can include the 'dist' folder to the repo like other modules:
https://github.com/instructure/ic-ajax
I use that as an example due to it being referenced in the ember-cli docs here:
http://www.ember-cli.com/#managing-dependencies
Any help would be appreciated.
Hopefully I am just making a newbie mistake and we can update the docs.
In Ember Data 1.0.0-beta.14 using store.metaForType got deprected.
I've created this model to extend django.contrib.auth User:
class UserProfile(models.Model):
user = models.OneToOneField(User)
company = models.CharField(max_length=100)
I have set up my resources:
class UserResource(ModelResource):
userprofile = fields.ToOneField('profiles.resources.UserProfileResource', 'userprofile')
class Meta:
queryset = User.objects.all()
resource_name = 'users'
allowed_methods = ['get', 'put', 'post', 'delete']
authorization = Authorization()
serializer = Serializer(formats=['json'])
always_return_data = True
class UserProfileResource(ModelResource):
user = fields.ToOneField(UserResource, 'user')
class Meta:
queryset = UserProfile.objects.all()
resource_name = 'userprofiles'
always_return_data = True
Also, I have set up my ember-data models:
App.Users = DS.Model.extend({
first_name: DS.attr('string'),
last_name: DS.attr('string'),
email: DS.attr('string'),
userprofile: DS.belongsTo('App.Userprofiles'),
fullName: function() {
return this.get('first_name') + ' ' + this.get('last_name');
}.property('first_name', 'last_name'),
didLoad: function() {
console.log('Developer model loaded', this);
}
});
App.Userprofiles = DS.Model.extend({
company: DS.attr('string'),
user: DS.belongsTo('App.Users'),
didLoad: function() {
console.log('Developer Profile model loaded', this);
}
});
However, when I check the created instances the userprofile filed is undefined. Any ideas on what the problem is?
Hi,
I am facing this error while trying to use the adapter with the latest versions:
Uncaught TypeError: Object [object Object] has no method 'extractSince'
ember version: // Version: v1.0.0-rc.1-259-gf557e37 // Last commit: f557e37 (2013-03-27 13:57:29 -0700)
ember data: // Last commit: 9d6686c (2013-03-22 19:26:49 -0700)
Any idea how to fix this?
Thanks
There is a serialisation error for hasMany relationships. The get(record, relationship.key)
at https://github.com/escalant3/ember-data-tastypie-adapter/blob/master/packages/ember-data-tastypie-adapter/lib/tastypie_serializer.js#L212 can return a promise. The .map()
on that returns an empty array, which is then sent in the request and deletes all the corresponding relationships on the server...
I have a resource with another full nested resource and I'm trying to update (PUT) the parent resource. The server side fails because it tries to re-create the nested resource even though it already exists (it gives me IntegrityError).
I noticed that the serializeHasMany
fails to serialise the nested resource id. When I change the code to serialise the id too then it works just fine.
Here's what I changed:
serializeHasMany: function(record, json, relationship) {
var key = relationship.key,
attrs = get(this, 'attrs'),
config = attrs && attrs[key] ? attrs[key] : false;
key = this.keyForRelationship ? this.keyForRelationship(key, "belongsTo") : key;
var relationshipType = DS.RelationshipChange.determineRelationshipType(record.constructor, relationship);
if (relationshipType === 'manyToNone' || relationshipType === 'manyToMany' || relationshipType === 'manyToOne') {
if (this.isEmbedded(config)) {
json[key] = get(record, key).map(function (relation) {
var data = relation.serialize();
//Here's what I changed - I just added this line
data.id = relation.get('id');
return data;
});
} else {
json[key] = get(record, relationship.key).map(function (next){
return this.relationshipToResourceUri(relationship, next);
}, this);
}
}
}
Our project is using Ember 1.3 (Canary) and Ember Data 1.0.0-beta.4 with a Django back-end.
We're in the process of moving to a tastypie generated API, and over the next few days I'll be building an adapter for the builds mentioned above. Over the next couple months we'll be configuring our tastypie to use sideloading, which means I'll also be building in support for it.
I'd like to know how much community interest there would be in advancing this library to support more recent versions of ember and ember-data, or whether I should consider this existing adapter a ghost town.
I've read through the code here (not much to read obviously) and while its meant for a very different version of ember-data), the update 5-7 months back to use RSVP promises, and the overall structure of the adapter are fairly compatible with ED1.0, although I think in addition to calling store.didSaveRecord( record , serialized )
it is now necessary to call store.updateId( record , serialized )
and record.adapterDidCommit( serialized )
(and note these methods belong to the store, not to the adapter).
I think this serializer is largely still relevant, although it lacks nested-record-create support and side-loading pipes to an empty function (an issue with most ED adapters right now, but one I've got a working solution to for the current DS.RESTAdapter).
Number of deprecations preventing upgrading from ember-data 1.13 to emder-data 2.0: ttp://emberjs.com/blog/2015/06/18/ember-data-1-13-released.html
In the most recent version of EmberData, whenever I use the TastyPieAdapater the toString method of a model always return this:
> App.SomeModel.toString() "(subclass of DS.Model)"
I believe this is related to this issue: emberjs/data#173
Because of 'rootForType' function, this means the URLs always end up looking like this: http://127.0.0.1:8000/api/v1/model)/1/
Any suggestions how to change this without overriding the toString() method on the DS.model?
I've set
authentication = SessionAuthentication() at my resourse.
Login at /admin/.
But server always returns 401 Not Authentificated.
How does ember-data-tastypie-adapter work with auth?
Thanks for this great module. It would be great if this adapter would be available on Bower.io so updates and installation can be automated.
Uncaught TypeError: Object #<Object> has no method 'sinceForType'
. Error caught on L85 when paginating records. Meta
is meta: {limit:20, next:?limit=20&offset=20, offset:0, previous:null, total_count:51}
with API_LIMIT_PER_PAGE
as default.
A few questions I have on concurrency, with a basic scenario such as:
How are we handling it? Number 4 should fail, right?
What is the default behavior in tastypie?
Is django USE_ETAGS flag mandatory for this to work? If it is, are we handling ETAGS?
I think we don't have any kind of tests covering this, if anyone has an example of this, I can write the tests and make sure the adapter is working.
Hi,
Just a quick question.
Why is the main property in the bower.json not specified?
I need it for a Grunt build process and am able to specify it myself, but was just wondering.
Thanks,
Koen
Upgrading to Ember 1.8 makes things fail (in the decamelize attribute function).
If you can't reproduce using one of the test cases you have, let me know, I'll try to get a working test case going.
Thanks a lot for your great work.
Uncaught TypeError: Object #<Object> has no method 'adapterDidCommit' ember-data.js:1833
DS.Store.Ember.Object.extend.didSaveRecord ember-data.js:1833
DS.Adapter.Ember.Object.extend.didSaveRecord ember-data.js:6785
DS.DjangoTastypieAdapter.DS.RESTAdapter.extend.didUpdateRecord tastypie_adapter.js:119
superWrapper
It happens during saving of existing Item. App.store.commit(), after item changes.
Not sure that it is a ember-data-tastypie-adapter problems, but looks like - yes.
I'm using latest ember-data and adapter.
I believe the parameter passed into adapterFor
here should be relationship.type rather than typeKey:
relationshipToResourceUri: function (relationship, value){
if (!value)
return value;
var store = relationship.type.store,
typeKey = relationship.type.typeKey;
return store.adapterFor(typeKey).buildURL(typeKey, get(value, 'id'));
},
ember-data looks for type.typeKey in the adapterFor function:
/**
Returns the adapter for a given type.
@method adapterFor
@private
@param {subclass of DS.Model} type
@return DS.Adapter
*/
adapterFor: function(type) {
var container = this.container, adapter;
if (container) {
adapter = container.lookup('adapter:' + type.typeKey) || container.lookup('adapter:application');
}
return adapter || get(this, 'defaultAdapter');
},
I ran the tests with latest version of Ember, Handlebars, and the Ember-states plugin, and all passed with 0.13 ember-data.
If I stick with the older 0.13 version of ember-data, should I be good to start developing with the release versions of the other Ember files?
Is there a plan to update when Ember-data 1.0 is released?
Make the adapter be an ember-cli addon. It's what the cool kids are doing, I think we should too.
Hi. I'm going through the ember guides, trying to connect my tastypie API to an ember application. I've pulled the latest ember, ember-data and ember-data-tastypie-adapter code from their respective repos. Getting my data out of the server, I get:
My ember application:
var HortaApp = Ember.Application.create();
HortaApp.store = DS.Store.create({
revision : 11,
adapter : DS.DjangoTastypieAdapter.extend(),
});
/* Models */
HortaApp.Garden = DS.Model.extend({
name : DS.attr('string'),
});
/* Views */
HortaApp.ApplicationView = Ember.View.extend({
templateName : 'application',
});
HortaApp.AllGardensView = Ember.View.extend({
templateName : 'all-gardens',
});
/* Controllers */
HortaApp.ApplicationController = Ember.Controller.extend();
HortaApp.AllGardensController = Ember.ArrayController.extend();
/* Routers */
HortaApp.Router = Ember.Router.extend();
HortaApp.Router.map(function(){
this.resource('allGardens', {path : '/gardens'}, function(){
this.route('new');
});
});
HortaApp.AllGardensRoute = Ember.Route.extend({
model : function(){
return HortaApp.Garden.find();
},
setupController : function(controller, model){
controller.set('content', model);
},
});
HortaApp.initialize();
when I visit the http://localhost:8000/#/gardens URL, using Firebug, I can see that the request for data is sent to the server and that the response is correct. Response:
{"meta": {"limit": 20, "next": null, "offset": 0, "previous": null, "total_count": 2}, "objects": [{"name": "Horta da Velha", "resource_uri": "/api/v1/garden/1/"}, {"name": "Horta do Monte", "resource_uri": "/api/v1/garden/2/"}]}
However, I am getting the following error in the console:
Error: assertion failed: Your server returned a hash with the key objects but you have no mapping for it
What could be the problem? Is my model badly defined? Maybe some convention name I am not respecting?
Thank you
I'm trying to use hasMany relation in ember models but the tastypie adapter throws and error resourceUri.split is not a function
as it gets and object and not a string
Object { id=4, resource_uri="/api/v1/option/4/",...}
The problem is in:
resourceUriToId: function (resourceUri) {
return resourceUri.split('/').reverse()[1];
},
Is it some configuration issue or a bug? ;)
Suppose you have two models:
Post, Comment Where Post hasMany Comments and Comment belongsTo Post
It should be possible to commit a transaction where both a new Post and Comment are created and related to each other.
Currently this fails as the Comment will attempt to save without an ID.
This could be accomplished by adapter logic to defer portions of the commit until the parent record is saved, or by adding support for saving records in an embedded manner.
There is a problem when working with latest ember-data.
Query with using of embbed field do not populate Object content properly,
Examples
s = App.Staple.find(1)
s._data.belongsTo.album
Object {created="2012-12-26T05:41:37", description="30a", ...}
p._data.belongsTo.language
Object {id="1", clientId=7, ...}
Looks like in beta 11 of Ember Data, they removed DS.RelationshipChange, moving the typeForRelationship
to a static method on DS.Model. This is causing an error looking for that method upon save.
I created a quick workaround for my code, but haven't tested it enough to create a PR yet. I'll create one here when it's ready.
It might be related with the use of an outdated ember-data
I have a field in model that has a relation to another model (DS.belongsTo). When I try to create a new object with a resource uri to the related object I get a 404 on the related object (that does exist).
tastypie_serializer.js (keyForBelongsTo) will add _id suffix: "field_id" instead of "field". Tastypie expects that the related field key is not suffixed when POSTed. When I remove the suffix - it works.
Hi
I'm not very experienced with javascript and I'm having a hard time connecting my tastypie API to an emberjs app.
My tastypie resource:
class GardenResource(ModelResource):
files = fields.ManyToManyField(MediaResource, 'files')
class Meta:
always_return_data = True
queryset = horta.models.Garden.objects.all()
resource_name = 'garden'
fields = ['name']
If I make a call to the API using cURL:
$ curl -H "Accept: application/json" "http://127.0.0.1:8000/api/v1/garden/"
I get back:
{
"meta": {
"limit": 20,
"next": null,
"offset": 0,
"previous": null,
"total_count": 2
},
"objects": [
{
"files": [],
"name": "Horta da Velha",
"resource_uri": "/api/v1/garden/1/"
},
{
"files": [],
"name": "Horta da Costa",
"resource_uri": "/api/v1/garden/2/"
}
]
}
The ember js file:
var HortaApp = Ember.Application.create();
HortaApp.store = DS.Store.create({
revision : 11,
adapter : DS.DjangoTastypieAdapter.extend({
serverDomain : 'http://127.0.0.1:8000',
namespace : 'api/v1',
}),
});
/* Models */
HortaApp.Garden = DS.Model.extend({
name : DS.attr('string'),
});
/* Views */
HortaApp.ApplicationView = Ember.View.extend({
templateName : 'application',
});
HortaApp.AllGardensView = Ember.View.extend({
templateName : 'all-gardens',
});
/* Controllers */
HortaApp.ApplicationController = Ember.Controller.extend();
HortaApp.AllGardensController = Ember.ArrayController.extend();
/* Routers */
HortaApp.Router = Ember.Router.extend({
enableLogging : true,
root : Ember.Route.extend({
index : Ember.Route.extend({
route : '/',
connectOutlets : function(router){
router.get('applicationController').connectOutlet(
'allGardens', HortaApp.Garden.find()
);
},
}),
}),
});
HortaApp.initialize();
When I run it through firebug I get:
STATEMANAGER: Entering root
STATEMANAGER: Sending event 'navigateAway' to state root.
STATEMANAGER: Sending event 'unroutePath' to state root.
STATEMANAGER: Sending event 'routePath' to state root.
STATEMANAGER: Entering root.index
TypeError: method is undefined
return method.apply(target || this, args || []);
It seems there is something wrong with the setting up of the models, as it doesn't
even get to making the request to the server. What could be the problem?
Thanks
I would like to create pagination for recordArray but looks like you dont use meta data that comes from Tastypie.
I have overriden the buildURL method to append a special param at the end of the url for certain models in my code.
App.store = DS.Store.create({
revision: REVISION,
adapter: DS.DjangoTastypieAdapter.extend({
serverDomain: "http://"+host,
namespace: "api/v1",
buildURL: function(record, suffix) {
return this._super(record,suffix) + '?specialParam=foo'
}
}),
});
However, when findMany the param is appended in the middle of the url
http://example.com/api/v1/?specialParam=foo/set/1;2/
This is because in findMany the ids are appended after buildURL is called.
findMany: function(store, type, ids) {
var url,
root = this.rootForType(type);
ids = this.serializeIds(ids);
// FindMany array through subset of resources
if (ids instanceof Array) {
ids = "set/" + ids.join(";") + '/';
}
url += ids;
url = this.buildURL(root);
this.ajax(url, "GET", {
success: function(json) {
this.didFindMany(store, type, json);
}
});
},
Your extractMany method never call extractRecordRepresentation
So for:
A = DS.Model.extend({
b: DS.belongsTo('App.B')
})
a = A.find({limit:1}) // {objects: [{//some_fields: b: {some_fields for B}}]}
a.objectAt(0).serialize()
fails, because we dont have store representation for b model.
Line 204 in didFindRecord:
store.load(type, id, json.objects);
I had to remove .objects
as json
was the actual object and not the metadata with an objects
key. I'm using your code with django-ember.
I am using createRecord to create a new instance of a model with a belongsTo relationship. When I commit my code fails because tastypie cannot deserialize the associated model. More specifically, looking at the response
I can see that instead of:
"developer":"/api/v1/users/1/"
the actual payload was:
"developer_id":"/api/v1/users/1/"
Looking in the tastypie_serializer.js I see that a "_id" is appended to that field. Removing this the request goes through. Is that a bug or am I missing something?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.