I am getting the following error:
FieldError at /blog/1/first-post/
Cannot resolve keyword u'slug' into field. Choices are: article, date, id, likes
Request Method: GET
Request URL: http://127.0.0.1:8000/blog/1/first-post/
Django Version: 1.6.2
Exception Type: FieldError
Exception Value:
Cannot resolve keyword u'slug' into field. Choices are: article, date, id, likes
My model:
class Article(models.Model):
title = models.CharField(max_length=20)
body = models.TextField()
image = models.ImageField(upload_to="/", blank=True, null=True)
slug = models.SlugField()
def save(self, *args, **kwargs):
if not self.id:
self.slug = slugify(self.title)
super(Article, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('article_detail', kwargs={'slug':self.slug, 'id':self.id})
def __unicode__(self):
return self.title
class Detail(models.Model):
article = models.ForeignKey(Article)
date = models.DateField()
likes = models.IntegerField()
def __unicode__(self):
return "%s %s" % (self.article.title, self.likes)
def get_absolute_url(self):
return reverse('detail_article', kwargs={'id':self.id})
View:
class ArticleDetail(DetailView):
model = Detail
template_name = "article_detail.html"
context_object_name = "details"
def get_queryset(self):
print self.kwargs['slug']
a = Article.objects.get(slug=self.kwargs['slug'])
# print Details.object.get()
# print Detail.objects.filter(article__slug=self.kwargs['slug']) fails with same error
return Detail.objects.filter(article=a)
urls.py (this is inside by blog app):
urlpatterns = patterns('',
url(r'all$', ArticleList.as_view(), name='blog_all'),
url(r'^(?P<id>\d+)/(?P<slug>[-\w\d]+)/$', ArticleDetail.as_view(), name='article_detail'),
url(r'^detail/?(P<id?\d+)/$', DetailArticle.as_view(), name='detail_article'),
url(r'^create$', ArticleCreateView.as_view(), name='blog_create'),
)
Basically the detailView of an article instance
will display the contents of detail
model that has foreignkey relationship to article model
. It is not the traditional way where the detail view of article
instance displays that instance.
Template here:
{% extends "base.html" %}
{% block content %}
{% for detail in details %}
<p>{{ detail.article.title }}</p>
<p>{{ detail.date }}</p>
<p>{{ detail.likes }}</p>
{% endfor %}
{% endblock %}
overriding the get_object(self, queryset=None)
method instead of DetailView get_queryset(self)
is an easier solution
class ArticleDetail(DetailView):
model = Detail
template_name = "article_detail.html"
context_object_name = "details"
def get_object(self, queryset=None):
slug = self.kwargs['slug']
a_obj = Article.objects.get(slug=slug)
try:
d_obj = Detail.objects.get(article=a_obj)
except Detail.DoesNotExist:
d_obj = None
except Detail.MultipleObjectsReturned:
#select the apt object
return d_obj
Solution: you need to rename slug parameter in url to other name, or in your view set slug_url_kwarg some other value - not 'slug'
Explanation: When you add to url, django tries to get object by slug and your model Detail has no slug field.
Link to django code: https://github.com/django/django/blob/master/django/views/generic/detail.py#L33
UPDATE
in SingleObjectMixin:
slug = self.kwargs.get(self.slug_url_kwarg, None)
...
elif slug is not None:
slug_field = self.get_slug_field()
queryset = queryset.filter(**{slug_field: slug})
so django gets slug from your url, tries to get slug field from Detail model and fails
Your view need to rewrite slug_url_kwarg attribute:
class ArticleDetail(DetailView):
model = Detail
template_name = "article_detail.html"
context_object_name = "details"
slug_url_kwarg = "not_slug" # this attribute
def get_queryset(self):
print self.kwargs['slug']
a = Article.objects.get(slug=self.kwargs['slug'])
# print Details.object.get()
# print Detail.objects.filter(article__slug=self.kwargs['slug']) fails with same error
return Detail.objects.filter(article=a)
but I think better way is to change to attribute in your url:
url(r'^(?P<id>\d+)/(?P<article_slug>[-\w\d]+)/$', ArticleDetail.as_view(), name='article_detail'),
and get article_slug from view kwargs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With