2013-04-14 4 views
4

장고를 읽고 구입했습니다. Django 1.5 Best Practices for Django는 클래스 기반 뷰의 예제가 있습니다. 이 구현 후에 양식을 제출 한 후에 오류가 발생합니다.Django 클래스 기반 뷰, get_absolute_url이 작동하지 않습니다.

ImproperlyConfigured at /NonProfitCreate/ 
No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model 

연구를하는 나는이 get_absolute_url 내 프로그램

에서 작업 할이 문제 Django - Class Based Generic View - "No URL to redirect to"

함께 온이 내 forms.py입니다

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
# 
# npp/forms.py 

from django import forms 

from .models import NonProfit 

class NonProfitCreateForm(forms.ModelForm): 
    class Meta: 
     model = NonProfit 
     fields = ("name","contact_name","email","phone","address","image","tags",) 

    def __init__(self, *args, **kwargs): 
     self.request = kwargs.pop('request', None) 
     return super(NonProfitCreateForm, self).__init__(*args, **kwargs) 

    def save(self, *args, **kwargs): 
     kwargs['commit']=False 
     obj = super(NonProfitCreateForm, self).save(*args, **kwargs) 
     if self.request: 
      obj.user = self.request.user 
      obj.save() 

class NonProfitUpdateForm(NonProfitCreateForm): 
    class Meta: 
     model = NonProfit 

이 내 모델입니다. py 및보기 파일

from django.db import models 
from django.contrib.auth.models import User 
from django.db.models import permalink 
from django_extensions.db.fields import AutoSlugField 
from django.contrib import admin 

from django.core.urlresolvers import reverse 

import tagging 
from tagging.models import Tag 
# Create your models here. 
''' this is for the Non-Profit Proccess ''' 

class NonProfit (models.Model): 
    User = models.ForeignKey(User) 
    name = models.CharField(max_length=100) 
    contact_name = models.CharField(max_length=100) 
    email = models.EmailField(max_length=75) 
    phone = models.CharField(max_length=20) 
    address = models.TextField(max_length=3000) 
    image = models.ImageField(upload_to='photos/%Y/%m/%d',blank=True) 


    slug = models.SlugField(max_length=128) 
    slug = AutoSlugField(('slug'), max_length=128, unique=True, populate_from=('name',)) 
    tags = tagging.fields.TagField() 

    def get_absolute_url(self): 
     return reverse("npp/nonprofit_detail", kwargs={"slug": self.slug}) 

    def __unicode__(self): 
     return self.name 

    def get_tags(self): 
     return Tag.objects.get_for_object(self) 




    # Create your views here. 
    # Auction/npp/views.py 

from Auction.views import ActionMixin 

from django.contrib import messages 
from django.views.generic import CreateView, UpdateView, DetailView 

from braces.views import LoginRequiredMixin 

from forms import NonProfitCreateForm,NonProfitUpdateForm 


from models import NonProfit 

class NonProfitCreateView(LoginRequiredMixin,ActionMixin,CreateView): 
    model = NonProfit 
    action = "created" 
    form_class = NonProfitCreateForm 

class NonProfitUpdateView(LoginRequiredMixin,ActionMixin,UpdateView): 
    model = NonProfit 
    action = "updated" 
    form_class = NonProfitUpdateForm 


class NonProfitDetailView(DetailView): 
    model = NonProfit 


# Auction/views.py 
class ActionMixin(object): 
    @property 
    def action(self): 
     msg = "{0} is missing action.".format(self.__class__) 
     raise NotImplementedError(msg) 

    def form_valid(self, form): 
     msg = "{0}!".format(self.action) 
     messages.info(self.request, msg) 
     return super(ActionMixin, self).form_valid(form) 
이 내 스택 트레이스, 장고 중괄호가 강조되어

url(
    regex=r'^NonProfitCreate/', 
    view=NonProfitCreateView.as_view(), 
    name='NonProfitCreate', 
), 
url(
    regex=r'^NonProfit/(?P<slug>[-\w\d]+)/', 
    view=NonProfitDetailView.as_view(), 
    name='NonProfit' 
    ) 

691,363,210

urls.py 및

/home/talisman/projects/Auction/Auction/views.py in form_valid 
     return super(ActionMixin, self).form_valid(form) 

EEnvironment: 


Request Method: POST 
Request URL: http://127.0.0.1:8000/NonProfitCreate/ 

Django Version: 1.5.1 
Python Version: 2.7.4 
Installed Applications: 
('django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.sites', 
'django.contrib.messages', 
'django.contrib.staticfiles', 
'django.contrib.admin', 
'django.contrib.admindocs', 
'django.contrib.comments', 
'django.contrib.sitemaps', 
'zinnia', 
'tagging', 
'mptt', 
'south', 
'misc', 
'adm', 
'registration', 
'npp', 
'blogs') 
Installed Middleware: 
('django.middleware.common.CommonMiddleware', 
'django.contrib.sessions.middleware.SessionMiddleware', 
'django.middleware.csrf.CsrfViewMiddleware', 
'django.contrib.auth.middleware.AuthenticationMiddleware', 
'django.contrib.messages.middleware.MessageMiddleware', 
'django.middleware.clickjacking.XFrameOptionsMiddleware') 


Traceback: 
File "/home/talisman/virt_env/Auction/local/lib/python2.7/site-packages/Django-1.5.1-py2.7.egg/django/core/handlers/base.py" in get_response 
    115.       response = callback(request, *callback_args, **callback_kwargs) 
File "/home/talisman/virt_env/Auction/local/lib/python2.7/site-packages/Django-1.5.1-py2.7.egg/django/views/generic/base.py" in view 
    68.    return self.dispatch(request, *args, **kwargs) 
File "/home/talisman/virt_env/Auction/local/lib/python2.7/site-packages/django_braces-1.0.0-py2.7.egg/braces/views.py" in dispatch 
    98.    **kwargs) 
File "/home/talisman/virt_env/Auction/local/lib/python2.7/site-packages/Django-1.5.1-py2.7.egg/django/views/generic/base.py" in dispatch 
    86.   return handler(request, *args, **kwargs) 
File "/home/talisman/virt_env/Auction/local/lib/python2.7/site-packages/Django-1.5.1-py2.7.egg/django/views/generic/edit.py" in post 
    199.   return super(BaseCreateView, self).post(request, *args, **kwargs) 
File "/home/talisman/virt_env/Auction/local/lib/python2.7/site-packages/Django-1.5.1-py2.7.egg/django/views/generic/edit.py" in post 
    165.    return self.form_valid(form) 
File "/home/talisman/projects/auction/Auction/views.py" in form_valid 
    54.  return super(ActionMixin, self).form_valid(form) 
File "/home/talisman/virt_env/Auction/local/lib/python2.7/site-packages/Django-1.5.1-py2.7.egg/django/views/generic/edit.py" in form_valid 
    128.   return super(ModelFormMixin, self).form_valid(form) 
File "/home/talisman/virt_env/Auction/local/lib/python2.7/site-packages/Django-1.5.1-py2.7.egg/django/views/generic/edit.py" in form_valid 
    65.   return HttpResponseRedirect(self.get_success_url()) 
File "/home/talisman/virt_env/Auction/local/lib/python2.7/site-packages/Django-1.5.1-py2.7.egg/django/views/generic/edit.py" in get_success_url 
    119.      "No URL to redirect to. Either provide a url or define" 

Exception Type: ImproperlyConfigured at /NonProfitCreate/ 
Exception Value: No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model. 
+0

'NonProfitCreateForm'을 보여주십시오. – Alasdair

+0

왜 manage.py 쉘에서 모델을 인스턴스화하지 않고 get_absolute_url을 호출하면된다. 거기에서 스택 추적으로 디버깅 할 수있다. – zallarak

+0

모델에 중복 인수 슬러그가 있습니다. –

답변

8

이 예외는 self.object = None 때문에 생산된다. self.object의 값은 form.save() 호출의 결과이므로이 오류의 가장 큰 이유는 save() 메서드를 NonProfitCreateForm에 다시 정의했지만 저장 한 개체를 반환하지 않는 것입니다.

Form.save() 메서드는 저장된 개체를 반환해야하며 None이 아니어야합니다.아래 그림과 같이 NonProfitCreateForm이 수정 될 수있는 당신의

:

class NonProfitCreateForm(forms.ModelForm): 
    ... 
    def save(self, *args, **kwargs): 
     kwargs['commit']=False 
     obj = super(NonProfitCreateForm, self).save(*args, **kwargs) 
     if self.request: 
      obj.user = self.request.user 
      obj.save() 
     return obj #<--- Return saved object to caller. 

입력 폼 데이터에서 모델 인스턴스를 생성됩니다 save() 방법의 처음 두 행. 그러나 commit=False이므로 개체는 이 아니며이 데이터베이스에 저장됩니다. 양식 인스턴스에 self.request이 없으면 반환 된 개체에는 데이터베이스 기본 키가 없으며 get_absolute_url은 계속 실패합니다.

따라서 인스턴스화시 request 매개 변수가 양식에 항상 전달되도록하고 싶습니다. 이것은 기본적으로 발생하지 않으므로 request 매개 변수를 사용하여 양식을 인스턴스화하기 위해보기 코드를 정렬해야합니다.

code for FormMixin을 살펴보면 인스턴스화 된 양식에 전달할 인수를 결정하는 get_form_kwargs 함수가 있음을 알 수 있습니다. 당신은 당신의보기 재정 get_form_kwargs이 같은 뭔가를 필요한 매개 변수를 추가하려면, 그래서 request=self.request 전달해야합니다

class NonProfitCreateView(LoginRequiredMixin,ActionMixin,CreateView): 
    model = NonProfit 
    action = "created" 
    form_class = NonProfitCreateForm 

    def get_form_kwargs(self): 
     # Ensure the current `request` is provided to NonProfitCreateForm. 
     kwargs = super(NonProfitCreateView, self).get_form_kwargs() 
     kwargs.update({ 'request': self.request }) 
     return kwargs 

그것은 아마 될 더 나은 아이디어를 수정 get_form_kwargs 기능 CreateView의 서브 클래스를 생성하고,이 NonProfitCreateView 하위 클래스에서 파생됩니다.

+0

난 네가 문제를 못 견뎌 왔다고 생각해. 불행히도 나는 이것에 대해 이해하고있다. 내 forms.py를 추가하면 해결 방법을 보여줄 수 있습니까? – Klanestro

+0

@Klanestro 답변이 업데이트되었습니다. –

1

시도는 get_absolute_url 방법에서 @permalink 장식을 제거합니다. reverse과 함께 사용할 수 없습니다. 다음 또한

Django documentation 상태 다음 permalink 장식이 더 이상 권장

. 대신 get_absolute_url 메서드 본문에 reverse()을 사용해야합니다.

+0

감사하지만 효과가 없습니다. 여전히 동일한 오류가 발생합니다. – Klanestro

3

reverse을 사용하는 경우 되돌리려는 URL 패턴의 이름을 사용하십시오.

은이 URL로 리디렉션 할 :

url(
    regex=r'^NonProfit/(?P<slug>[-\w\d]+)/', 
    view=NonProfitDetailView.as_view(), 
    name='NonProfit' 
    ) 

따라서 귀하의 get_absolute_url 방법이 있어야한다 :

def get_absolute_url(self): 
    return reverse("NonProfit", kwargs={"slug": self.slug}) 
+1

동일한 오류가 발생합니다. – Klanestro

+0

다른 사람들에게는 'get_absolute_url'이 원본에 속한 것이 분명하지 않습니다. 모델은 UpdateView/CreateView가 https://docs.djangoproject.com/en/1.9/ref/class-based-views/generic-editing/ 맨 위에 설명 된대로 기반을두고 있습니다 (중요한 참고 사항 중 일부는 이 페이지의 예제에서는 myapp/models.py에서 저자 모델이 다음과 같이 정의되었다고 가정합니다.) – sage

1

당신은 당신의 클래스 기반 뷰의 get_success_url 기능을 대체 할 수 있습니다. 이처럼 : 유효한 편집 후 재 시도 할 때

def get_success_url(self): 
    return reverse("NonProfit", kwargs={"slug": self.object.slug}) 
+0

'CreateView' (또는'ModelFormMixin'을 상속받은 다른 뷰)에서이 작업을 수행하면 안되기 때문에 ['ModelFormMixin.get_success_url'] (https://github.com/django/django/blob/1.5/django/views/generic/edit.py#L108) 메소드는 인스턴스의 get_absolute_url을 호출하여 성공 URL. – Alasdair

+0

역방향 URL에 대한 요점은 정상이지만이 오류와 관련이 없습니다. 문제는'get_absolute_url'을 찾을 수 없다는 것입니다. 귀하의 해결책은 반대되는 일치 발견 오류가없는 것입니다. – Peyman

관련 문제