如何在 Django 中使用 ManytoMany / ForeignKey 更新模型
How to update a model with ManytoMany / ForeignKey in Django
我有一个模型 Study
包含许多 Targets
(ManyToManyField) 每个 Target
包含一个 Location (外键):
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)
在我看来,我想更新指定研究中的位置 -> 目标
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')
不知道对不对
据我了解,您正在尝试在 Location 模型中创建新的位置对象,并将这个新创建的位置对象更新为目标对象,该对象是根据 data['study'] 和 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')
一目了然,这就够用了。
study_to_update.targets.all()
是一个查询集,因此您可以使用 .filter()
等搜索它,而不是遍历 targets_to_update
:
target = study_to_update.targets.filter( uid=data["target"]).first()
if target is not None: # first() may return nothing
...
我不完全明白下一部分应该做什么。要更新 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
这将更新保留在研究对象的 many-to-many 列表中的特定 target
对象(数据库行)的位置。您不需要保存 study_to_update
.
如果您想要对 study.targets
进行操作,您可以使用 study.targets.add( target_instance)
或 .remove( target_instance)
。 target_instance
需要保存到数据库中才能添加。
可能有助于记住 many-to-many 是作为一个数据库 table 实现的,每行有两个外键。在这种情况下,一个标识一个 study
对象并标识一个 target
实例。 table 由 Django 在幕后管理,但将其概念化可能会有用。
我有一个模型 Study
包含许多 Targets
(ManyToManyField) 每个 Target
包含一个 Location (外键):
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)
在我看来,我想更新指定研究中的位置 -> 目标
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')
不知道对不对
据我了解,您正在尝试在 Location 模型中创建新的位置对象,并将这个新创建的位置对象更新为目标对象,该对象是根据 data['study'] 和 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')
一目了然,这就够用了。
study_to_update.targets.all()
是一个查询集,因此您可以使用 .filter()
等搜索它,而不是遍历 targets_to_update
:
target = study_to_update.targets.filter( uid=data["target"]).first()
if target is not None: # first() may return nothing
...
我不完全明白下一部分应该做什么。要更新 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
这将更新保留在研究对象的 many-to-many 列表中的特定 target
对象(数据库行)的位置。您不需要保存 study_to_update
.
如果您想要对 study.targets
进行操作,您可以使用 study.targets.add( target_instance)
或 .remove( target_instance)
。 target_instance
需要保存到数据库中才能添加。
可能有助于记住 many-to-many 是作为一个数据库 table 实现的,每行有两个外键。在这种情况下,一个标识一个 study
对象并标识一个 target
实例。 table 由 Django 在幕后管理,但将其概念化可能会有用。