Django / 如何从特定字段获取主键?

Django / How to get the primary key from a specific field?

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?

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 对象,name 字段的值为 "world"。这将导致调用 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 or get_or_create

看到这个:The pk lookup shortcut.

django 文档声明主键具有等效项,在本例中为 pk。因此,如果您在模型中声明了一个主键(假设我们称它为 code),您可以通过 codepk 访问它。这对于应用过滤器(如上面的 link)或获取特定属性都很有用。

现在你的问题是如何从事件名称中获取关联的主键,我将在下面向你展示一些解决方案,这些解决方案会对你如何声明模型产生影响。

一个。使用 scenes.objects.get(): 如果您使用此方法,则必须考虑两件事:

  1. 搜索存在,它不会退出,它会引发 Model.DoesNotExist 异常。
  2. 搜索 return 只有 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 with other methods like first() or last()

所以我推荐你re-make这样的模特:

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

或者如果您不想将 id 更改为主键,则使用 SlugField 如 pk 或唯一字段

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

如果您希望在 URL 中使用事件名称,则 slugfield 是理想选择。