Question

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 %}
Was it helpful?

Solution 2

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

OTHER TIPS

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
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top