Reputation: 3624
I am trying to use an attribute created using the @property
decorator im my model as a slug field for django DetailsView
, as follow:
class Province(models.Model):
name = models.CharField(max_length=30)
code = models.CharField(max_length=10)
@property
def slug(self):
return slugify(self.name)
My url:
path("map/<slug:slug>", MyView.as_view())
My view:
class MyView(DetailView):
template_name="myapp/map.html"
context_object_name = "province"
model = Province
But when accessing page I get the following exception:
Cannot resolve keyword 'slug' into field. Choices are: code, id, name
Is there a way to solve this, without using explicit SlugField
?
Upvotes: 1
Views: 301
Reputation: 26
That's not a good solution, in your model you don't have SlugField and you don't store slug in db. So you can't query off of a property - that's the reason it doesn't work.
Upvotes: 1
Reputation: 476977
Short answer: you can not store the slug as a @property
since then it is not stored in the database.
The problem is that you can not filter at the database side on the slug now, since it does not exists there, a property only exists at the Django/Python level.
A slug should therefore be stored in the database. A DetailView
, will make a query that looks for the record with the given slug at the database side. A SlugField
, or one of its subclasses, will normally add a db_index=True
on the field, and thus the database will make an index to lookup the record effectively.
If you do not want to implement methods to specify the slug, you can make use of the AutoSlugField
field, from django-autoslug
package. You install this with:
pip3 install django-autoslug
in your virtual environment. Next, you can add this field with:
from autoslug import AutoSlugField
from django.db import models
class Province(models.Model):
name = models.CharField(max_length=30)
code = models.CharField(max_length=10)
slug = AutoSlugField(populate_from='name')
Upvotes: 1