Django / Как получить первичный ключ из определенного поля?

Models.py

class scenes(models.Model):
    name = models.CharField('Event name', max_length=120)
    record_date = models.DateTimeField('Event date')

Допустим, я записал сцену с name="world"

В файле views.py, как я могу запросить pk из поля name?

from .models import scenes
 scene = scenes.objects.get('what should I put here to get the pk associated with name World ?')

Когда я вошел :

scene = scenes.objects.get(name='world').pk

Я получил ошибку :

UnboundLocalError: локальная переменная 'scenes' ссылается перед присвоением

Простым способом было бы просто:

# views.py

from .models import scenes

scene = scenes.objects.get(name="world")
scene_id = scene.pk # This contains the pk of the scene object

Django попытается получить уникальный объект с "world" в качестве значения для поля name. С вашим текущим кодом это имеет проблему:

  • Ваше поле name не является unique, поэтому ваша БД может содержать различные scenes объекты с "world" значением для поля name. Это приведет к проблемам при вызове get. Чтобы решить эту проблему, можно добавить unique=True при определении поля:
# models.py

class scenes(models.Model):
    name = models.CharField('Event name', max_length=120, unique=True)
    record_date = models.DateTimeField('Event date')

Это гарантирует, что ваша БД не будет содержать объектов с одинаковыми именами.

Обратите внимание, что если не существует объекта со значением name, равным "world", вы также получите ошибку. В зависимости от контекста, в котором вы это используете, вам следует рассмотреть get_object_or_404 или get_or_create

смотрите здесь: Ярлык поиска pk.

В документации django заявлено, что первичные ключи имеют эквивалент, в данном случае это pk. Поэтому если вы объявили первичный ключ в вашей модели (допустим, мы назвали его code), вы можете получить к нему доступ как code или pk. Это полезно как для применения фильтров (как в ссылке выше), так и для получения конкретного атрибута.

Теперь ваш вопрос в том, как получить связанный первичный ключ из имени события, я покажу вам ниже несколько решений с последствиями того, как вы объявили модель.

A. Использование scenes.objects.get(): Если вы используете этот метод, вы должны принять во внимание две вещи:

  1. Если поиск существует, он не завершается, возникает Model.DoesNotExist исключение.
  2. Что поиск возвращает только 1 объект, если найдено более одного объекта, то возникает Model.MultipleObjectsReturned исключение:

посмотрите Queryset get() method

Итак, если мы проигнорируем второе, то блок кода будет выглядеть следующим образом

# we have 1 object with the name `world`

try:
    scene = scenes.objects.get(name="world")
    scene_pk = scene.pk
except scenes.DoesNotExist: 
    print("The Scene does not Exists")

но второй вы должны использовать Queryset filter() method с другими методами, такими как first() или last()

Поэтому я рекомендую вам переделать модель следующим образом:

class scenes(models.Model):
    name = models.CharField('Event name',unique=True, max_length=120)
    record_date = models.DateTimeField('Event date')

или использовать SlugField как pk или уникальное поле, если вы не хотите менять id как первичный ключ

class scenes(models.Model):
    name = models.CharField('Event name', max_length=120)
    slug = models.SlugField(unique=True)
    record_date = models.DateTimeField('Event date')

slugfield идеально подходит, если вы хотите использовать название мероприятия в URL.

Вернуться на верх