I am using the Loopback framework, and have modelA which is in a many-to-many relation with modelB.
I want to know if it's possible to relate multiple items from modelB to modelA.
There is currently a way to relate one item with this call:
/modelA/{id}/modelB/rel/{fk}
Is there any way to perform this in a bulk operation?
If I understand your question correctly, I think you can simply do it through a filter. ModelA has many modelBs, Let me assume the relation name is 'modelBs'
modelA.find({
where: [your filter option on model A]
include: {
relation: 'modelBs',
scope: {
[your filters on model B]
}
}
})
in restful way:
/modelAs?filter[include]=modelBs&filter[where]....
The official documentation may help: https://docs.strongloop.com/display/public/LB/Querying+data
It seems to be HasManyThrough model.
I believe your model names starts with lowercase but ideally it should be ModelA and ModelB and their instances can then be saved in modelA and modelB variables.
In order to use add method, you will need to first find instance of ModelA first using ModelA.findById which you can save in modelA variable and then use the following code:
modelA.modelBs.add(modelBFieldsObject, function(err, patient) {
...
});
where modelBs should be the name of relation in the ModalA.json file as in
"relations": {
"modelBs": {
"type": "hasMany",
"model": "ModelB",
"foreignKey": "modelAId",
"through": "ModelAModelB",
"keyThrough": "modelBId"
}
...
I think it should be allowed to pass an array of modelBFieldsObject to create multiple instances as in
modelA.modelBs.add([modelBFieldsObject, modelBFieldsObject], function(err, patient) {
...
});
Tip: For clarity, name your models beginning with upper case letter and their instance variable in camelCase format.
References: Methods added to the model.
Related
I have a Model Product with business methods. My model contains relationship with Models Item and Dealer.
Let's say my Product is serialized as / can be created from:
{
"name": "productA",
"items": [2,3,13],
"dealer": [1,2]
}
I can for instance run Product.simulate():
class Product(Models):
....
def simulate(self):
```dummy function to illustrate```
return sum(i.price for i in self.items.all()) / len(i.dealer.all())
I would like to be able to compute Product.simulation with values in a dictionnary without creating Product instance. I have multiple signals and batch operation on Product Model I dont want to run on the only for simulation objects.
I could create a for_simulation attribute on Product and specify on my signals / batch operation to don't run on those instances but it seems do lead to duplicate code and be forgotten on some signals / batch.
On the other hand, I could rewrite all my methods in Product, Item, Dealer to work with dict as input but there's a lot of them.
Is there a better way to achieve my goal ? Ideally I would like to be able to do something like:
p = Product({
"name": "productA",
"items": [2,3,13],
"dealer": [1,2]
})
p.simulation()
I cannot: my instances need to be saved to build relationships.
It is my first question here, after reading the similar questions I did not find what I need, thanks for your help.
I am creating a fairly simple API but I want to use best practices at the security level.
Requirement: There is a table in SQL Server with +5 million records that I should ONLY allow READ (all fields) and UPDATE (one field). This is so that a data scientist consumes data from this table and through a predictive model (I think) can assign a value to each record.
For this I mainly need 2 things:
That only one field is updated despite sending all the fields of the table in the Json (I think I have achieved it with my serializer).
And, where I have problems, is in disabling the creation of new records when updating one that does not exist.
I am using an UpdateAPIView to allow trying to allow a bulk update using a json like this (subrrogate_key is in my table and I use lookup_field to:
[
{
"subrrogate_key": "A1",
"class": "A"
},
{
"subrrogate_key": "A2",
"class": "B"
},
{
"subrrogate_key": "A3",
"class": "C"
},
]
When using the partial_update methods use update and this perform_update and this finally calls save and the default operation is to insert a new record if the primary key (or the one specified in lookup_field) is not found.
If I overwrite them, how can I make a new record not be inserted, and only update the field if it exists?
I tried:
Model.objects.filter (subrrogate_key = ['subrrogate_key']). Update (class = ['class])
Model.objects.update_or_create (...)
They work fine if all the keys in the Json exist, because if a new one comes they will insert (I don't want this).
P.S. I use a translator, sorry.
perform_update will create a new record if you passed a serializer that doesn't have an instance. Depending on how you wrote your view, you can simply check if there is an instance in the serializer before calling save in perform_update to prevent creating a new record:
def perform_update(self, serializer):
if not serializer.instance:
return
serializer.save()
Django implements that feature through the use of either force_update or update_fields during save().
https://docs.djangoproject.com/en/3.2/ref/models/instances/#forcing-an-insert-or-update
https://docs.djangoproject.com/en/3.2/ref/models/instances/#specifying-which-fields-to-save
https://docs.djangoproject.com/en/3.2/ref/models/instances/#saving-objects
In some rare circumstances, it’s necessary to be able to force the
save() method to perform an SQL INSERT and not fall back to doing an
UPDATE. Or vice-versa: update, if possible, but not insert a new row.
In these cases you can pass the force_insert=True or force_update=True
parameters to the save() method.
model_obj.save(force_update=True)
or
model_obj.save(update_fields=['field1', 'field2'])
I have a model A which has an one2mny relation with another model B and the later has also an one2many relation with a model C.
I want to use self.update to update the one2many relation in the model A in and onchange method so accordingly update the one2many relation in the model B.
I have managed to update the first one but the second one is not updated here what i have done :
temp.append((0,0,{
'periode':periode,
'ca':ca,
'loc':loc,
'line_rs':line_rsc,
}))
self.update({
'periode_line':temp
})
where line_rsc is a list that should be used to update the second
one2many relation
Thanks
secod pic (secod one2many relation):
i tried this using the new api and it seems to be working just fine:
# this will add the new record to existing records
#api.onchange(..)
def .....(self):
self.update(
{'o2m_1_field': [{
'o2m_1_field_name': 'value',
'o2m_1_field_o2m_2_name': [{'o2m_2_field': 'value'}]
}]
}
)
this logic works fine in new api.
or you can do it like this
# this will add the new record to existing records
self.o2m_1_field += self.env['o2m.1.model.name'].new({
'o2m_1_field_name': 'value',
'o2m_1_field_o2m_2_name': [{'o2m_2_field': 'value'}]
})
if this is not working for you and giving you bad query error then you need to
use the latest version of odoo 8 because a lot has been changing you can even
do onchange on a o2m_field now ...
I defined 3 models in Loopback: job, contact and job_contact(through model) and using hasManyThrough relations defined below relation:
job has many contact through job_contact.
and I used the code below to find contacts by job through job_contact
job.findById(id, {
include: {
relation:'contact',
where :{deleted: false}, // no working here
scope:{
where:{deleted: false} // here will add condition on contact table
}
}
})
Someone got any ideas? How can I put conditions on "through" model, job_contact model, in this case?
I have found it is not possible to interact with the through model with filters on queries the two other models. If you want to access the through model you need to query it independently.
See part More Info at the bottom of the answer here and the linked github discussion.
How can I create relationships via slc or by directly editing models in a text editor?
I could not find a way to do so using strong arc composer. Does this feature exist?
You cannot create relations using Arc (unfortunately!). It's sure nice to have.
To create relations you can use the command in the cli from the project's root:
slc loopback:relation
This will prompt you with the models available. You can then select the type of relationship you want to have with the selected models. eg, one to many or many to many.
Then you can see the modified .json file in the common folder to view the relations created.
Alternatively, you can also edit the .json file directly. see the example which sets the relation between user and user-tokens
{
"name": "User",
. .
.
"relations": { // relations
"accessTokens": { // specify relation name
"type": "hasMany", // type of relation
"model": "AccessToken", // model to which relation is made
"foreignKey": "userId" // foreign key
}
}
}