Reputation: 141
I have a model Study
containing many Targets
(ManyToManyField) Each Target
contains a Location (ForeignKey):
class Study(models.Model):
uid = models.AutoField(primary_key=True)
targets = models.ManyToManyField(Target)
class Target(models.Model):
uid = models.AutoField(primary_key=True)
location = models.ForeignKey(Location, on_delete=models.CASCADE, null=True, blank=True )
class Localization(models.Model):
x = models.FloatField(blank=True)
in my view I want to update the Location that is in a specified Study -> Target
def update_locations(request):
data = json.loads(request.body.decode('utf-8'))
if request.method == 'POST':
study_to_update = Study.objects.get(uid = data["study"])
targets = study_to_update.targets.all()
target_to_update = [target for target in targets if target.uid == data["target"]][0]
new_location = Location(x = data["location"])
#target_to_update.remove(?)
#target_to_update.add(new_location)
study_to_update.save()
else:
return HttpResponseForbidden('Erreur dans la requéte')
I don't know if this is right or not
Upvotes: 1
Views: 817
Reputation: 8192
At a glance, that will work as far as it goes.
study_to_update.targets.all()
is a queryset, so you can search it using .filter()
etc. instead of iterating through targets_to_update
:
target = study_to_update.targets.filter( uid=data["target"]).first()
if target is not None: # first() may return nothing
...
I don't fully understand what the next part is supposed to do. To update the location in target
:
new_location = Location( ...)
new_location.save() # won't have a pk until saved, can't be a ForeignKey until it does
target.location = new_location
target.save() # update location
This will update the location for a particular target
object (DB row) which remains in the study object's many-to-many list. You don't need to save study_to_update
.
If instead or as well you want to operate on study.targets
you would use study.targets.add( target_instance)
or .remove( target_instance)
. target_instance
needs to be saved to the DB before you can add it.
It may help to remember that many-to-many is implemented as a DB table with two ForeignKeys per row. In this case one identifies a study
object and the identifies a target
instance. This table is managed by Django behind the scenes, but conceptualizing it may be useful.
Upvotes: 1
Reputation: 585
As per my understanding, you are trying to create new location object in Location model and update this newly created location object into target object, which was filtered based on data['study'] and data['target'].
def update_locations(request):
data = json.loads(request.body.decode('utf-8'))
if request.method == 'POST':
study_to_update = Study.objects.get(uid = data["study"])
targets = study_to_update.targets.all()
target_to_update = [target for target in targets if target.uid == data["target"]][0]
# new location object is created.
new_location = Location.objects.create(x=data['location'])
# since new_location can point to multiple rows of Target model, we add the 'target_to_update' into the relationship set. new_location will be in relationship with target_to_update object.
new_location.target_set.add(target_to_update)
else:
return HttpResponseForbidden('Erreur dans la requéte')
Upvotes: 0