Reputation: 533
Models.py
class scenes(models.Model):
name = models.CharField('Event name', max_length=120)
record_date = models.DateTimeField('Event date')
Let's say I have recorded a scenes with name="world"
In views.py, how can I query the pk from the name field ?
from .models import scenes
scene = scenes.objects.get('what should I put here to get the pk associated with name World ?')
When I entered :
scene = scenes.objects.get(name='world').pk
I got an error :
UnboundLocalError: local variable 'scenes' referenced before assignment
Upvotes: 2
Views: 2239
Reputation: 181
see this: The pk lookup shortcut.
The django documentation declares that primary keys have an equivalent, in this case it is pk
. So if you declared a primary key in your model (let's say we called it code
) you could access it as code
or pk
. This is useful both to apply filters (like the link above) or to obtain a specific attribute.
Now your question is how to obtain the associated primary key from the name of the event, I will show you below some solutions with consequences to how you declared the model.
A. Using scenes.objects.get()
:
If you use this method you must take into consideration two things:
Model.DoesNotExist
exception.Model.MultipleObjectsReturned
exception:please see the Queryset get() method
so if we ignore the second thing, the block of code is like this
# 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")
but the second you should use Queryset filter() method
with other methods like first()
or last()
So I recommend you re-make the Model like this:
class scenes(models.Model):
name = models.CharField('Event name',unique=True, max_length=120)
record_date = models.DateTimeField('Event date')
or using a SlugField
like pk or unique field if you don't wanna change the id as primary key
class scenes(models.Model):
name = models.CharField('Event name', max_length=120)
slug = models.SlugField(unique=True)
record_date = models.DateTimeField('Event date')
the slugfield is ideal if you wish to use the name of the event in the URL.
Upvotes: 1
Reputation: 789
The easy way to go with that would be to just:
# 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 will try to fetch a unique object with "world"
as a value for the name
field. With your current code this has an issue:
name
field is not unique
so your DB may contain different scenes
objects with the "world"
value for the name
field. This will lead to problems when calling get
. To solve that you could add unique=True
when defining the field:# models.py
class scenes(models.Model):
name = models.CharField('Event name', max_length=120, unique=True)
record_date = models.DateTimeField('Event date')
This will ensure that your DB won't contain objects with the same name.
Note also that if there's no object with name
value equal to "world"
you'll get an error too. Depending on the context you are using this, you should consider get_object_or_404 or get_or_create
Upvotes: 2