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
CodePudding user response:
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:
- Your
name
field is notunique
so your DB may contain differentscenes
objects with the"world"
value for thename
field. This will lead to problems when callingget
. To solve that you could addunique=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
CodePudding user response:
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:
- That the search exists, it not exit, it raises
Model.DoesNotExist
exception. - That the search return only 1 object,it finds more than one object, it raises a
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.