Навигация во многих отношениях в обоих направлениях - PullRequest
1 голос
/ 09 мая 2019

Я пытаюсь понять, как Django возвращает столбцы из внешних ключей, особенно из-за ситуации с m2m, легко в SQL, но я пытаюсь войти в Django.

В этом примере у меня есть 3 модели, Sample, который имеет m2m с Container

и Location, который имеет 1-ко-многим с Container.

Сценарий 1a: Из таблицы Sample получите контейнеры, которыеобразец находится в (возвращаются sample_number и container_name).

Сценарий 1b: Из контейнера получают связанные образцы (возвращают container_number и sample_number).

Сценарий 2a: Из модели местоположения получают контейнеры (location_name и container_names).

Сценарий 2b: Из модели Контейнера получите местоположение (Container_name и location_name).

Надеемся, что это послужит хорошим общим справочным материалом для других.

# 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 %}

1 Ответ

0 голосов
/ 10 мая 2019

Сценарий 1a: Из таблицы Sample получите контейнеры, в которых находится образец (верните sample_number и container_name).

container_set = sample.containers.all()
for container in container_set:
    print([container.container_name, sample.sample_name])

Сценарий 1b: Из контейнера получите соответствующие образцы (вернуть параметр container_number и sample_number).

sample_set = container.samples.all()
for sample in sample_set:
    print([sample.sample_number, container.container_number])

Сценарий 2a: Из модели местоположения получить контейнеры (имена_емей и контейнеров).

container_set = location.location.all() # You have Container.location_id.related_name = 'location', I don't know why.
for container in container_set:
    print([location.location_name, container.container_name])

Сценарий2b: Из модели «Контейнер» получите местоположение («Имя_ контейнера» и «Имя_ местоположения»).

print([container.container_name, container.location_id.location_name])

Также ваши модели должны быть написаны следующим образом:

# 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 - это поле в ссылочной модели для отношения, которое необходимо вернуть обратно к текущей модели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...