如何在 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 在幕后管理,但将其概念化可能会有用。