Django 在两个方向上导航许多关系

Django 在两个方向上导航许多关系,django,Django,我试图理解Django如何从外键返回列,特别是m2m情况,这在SQL中很容易理解,但我试图了解Django 在这个示例中,我有3个模型,示例中有一个带有容器的m2m 和具有1对多容器的位置 场景1a:从样本表中获取样本在返回样本编号和容器名称中的容器 场景1b:从容器中获取相关的样本返回容器号和样本号 sample_set = container.samples.all() for sample in sample_set: print([sample.sample_number, co

我试图理解Django如何从外键返回列,特别是m2m情况,这在SQL中很容易理解,但我试图了解Django

在这个示例中,我有3个模型,示例中有一个带有容器的m2m

和具有1对多容器的位置

场景1a:从样本表中获取样本在返回样本编号和容器名称中的容器

场景1b:从容器中获取相关的样本返回容器号和样本号

sample_set = container.samples.all()
for sample in sample_set:
    print([sample.sample_number, container.container_number])
场景2a:从位置模型获取容器位置名称和容器名称

场景2b:从容器模型获取位置容器名称和位置名称

希望这将为其他人提供一个良好的总体参考

# models.py
class Location(models.Model):
    location_id = models.AutoField(primary_key=True)
    location_name = models.CharField(max_length=100, blank=True, null=True)

class Sample(models.Model):
    sample_id = models.AutoField(primary_key=True)
    sample_number = models.IntegerField()

class Container(models.Model): #like a friend
    container_id = models.AutoField(primary_key=True)
    container_name = models.CharField(max_length=50, blank=True, null=True)
    location_id = models.ForeignKey(Location, db_column='location_id', on_delete = models.PROTECT, related_name = 'location')
    samples = models.ManyToManyField('Sample', through='ContainerSamples', related_name='containers')

# views.py - Implements a filter
def detailcontainer(request, container_id):
    container = get_object_or_404(Container, pk=container_id)
    samples = container.samples.all()
    container_contents = container.samples.all()
    unassigned_samples = Sample.objects.all()

    qs = Sample.objects.all()

    context = {
        'queryset': qs,
        'container':container,
        'container_contents': container_contents,
        'unassigned_samples': unassigned_samples,
    }
    return render(request, 'container/detailcontainer.html', context)

# templates

{% for unassigned in unassigned_samples %}

# 1a [solved]
{% for unassigned in unassigned_samples %}
  {{ unassigned.sample_number }}
  {% for container in unassigned.containers.all %}
    {{ container.location_id }}.{{ container.container_name }}
  {% endfor %}
{% endfor %}

# 1b
{{ unassigned.____________ }} # the container_name
{{ unassigned.____________ }} # the related samples (sample_number)

# 2a
{{ unassigned.____________ }} # the location_name
{{ unassigned.____________ }} # the related container names (container_name)

# 2b
{{ unassigned.____________ }} # the container_name
{{ unassigned.____________ }} # the location_name

{% endfor %}
场景1a:从样本表中获取样本在返回样本编号和容器名称中的容器

场景1b:从容器中获取相关的样本返回容器号和样本号

sample_set = container.samples.all()
for sample in sample_set:
    print([sample.sample_number, container.container_number])
场景2a:从位置模型获取容器位置名称和容器名称

场景2b:从容器模型获取位置容器名称和位置名称

此外,您的模型应编写如下:

# models.py
class Location(models.Model):
    name = models.CharField(max_length=100, blank=True, null=True)

class Sample(models.Model):
    number = models.IntegerField()

class Container(models.Model): #like a friend
    container = models.AutoField(primary_key=True)
    name = models.CharField(max_length=50, blank=True, null=True)
    location = models.ForeignKey(Location, on_delete = models.PROTECT, related_name='containers')
    samples = models.ManyToManyField(Sample, through='ContainerSamples', related_name='containers')
如果对模型上的“自动”字段使用相同的定义,则没有理由添加它。在模型上定义属性(如名称)时,不应在其前面加上模型名称。应该理解的是,这是模型的名称。最后,related_name是引用模型上的字段,用于将关系遍历回当前模型

场景1a:从样本表中获取样本在返回样本编号和容器名称中的容器

场景1b:从容器中获取相关的样本返回容器号和样本号

sample_set = container.samples.all()
for sample in sample_set:
    print([sample.sample_number, container.container_number])
场景2a:从位置模型获取容器位置名称和容器名称

场景2b:从容器模型获取位置容器名称和位置名称

此外,您的模型应编写如下:

# models.py
class Location(models.Model):
    name = models.CharField(max_length=100, blank=True, null=True)

class Sample(models.Model):
    number = models.IntegerField()

class Container(models.Model): #like a friend
    container = models.AutoField(primary_key=True)
    name = models.CharField(max_length=50, blank=True, null=True)
    location = models.ForeignKey(Location, on_delete = models.PROTECT, related_name='containers')
    samples = models.ManyToManyField(Sample, through='ContainerSamples', related_name='containers')

如果对模型上的“自动”字段使用相同的定义,则没有理由添加它。在模型上定义属性(如名称)时,不应在其前面加上模型名称。应该理解的是,这是模型的名称。最后,related_name是引用模型上的字段,用于将关系遍历回当前模型。

您查看了文档的这一部分了吗?它很好地描述了如何使用ManyToManyField。向下滚动到part Article对象可以访问其相关的发布对象:您好,是的,我首先查看了它,但在视图/模板的上下文中我无法理解它。我在shell中尝试了Sample.container\u set,它为我提供了m2m\u描述符,但我找不到container\u name属性。我已经为1a添加了一个解决方案,请评论是否有更好的方法。您是否已经查看了文档的这一部分?它很好地描述了如何使用ManyToManyField。向下滚动到part Article对象可以访问其相关的发布对象:您好,是的,我首先查看了它,但在视图/模板的上下文中我无法理解它。我在shell中尝试了Sample.container\u set,它为我提供了m2m\u描述符,但我找不到container\u name属性。我已经为1a添加了一个解决方案,请评论是否有更好的方法