没有要重定向到的 URL。在模型上提供 url 或定义 get_absolute_url 方法
No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model
我正在使用 CreateView 构建表单。 CreateView 是从 DetailView 调用的。提交表单后,我希望将经过验证的提交数据返回到初始 DetailView。
DetailView 调用 CreateView 就好了。表单按预期工作,直到它被提交。然后,我收到此错误:No URL 要重定向到。在模型上提供 url 或定义 get_absolute_url 方法。
我尝试使用 ,但它引发了同样的错误。我尝试传递数据并通过调用 CreateView 的 URL 重定向。我仍然遇到同样的错误。
谁能告诉我如何将 CreateView 重定向回原始 DetailView(并传回经过验证的数据?
models.py
class Lawyer(models.Model):
name = models.CharField(max_length=100, default='')
practice_area = models.CharField(max_length=100, default='')
address = models.CharField(max_length=255, default='')
city = models.CharField(max_length=50, default='')
state = models.CharField(max_length=2, default='')
zipcode = models.CharField(max_length=10, default='')
telephone = models.CharField(max_length=15, default='')
years_practice = models.IntegerField(default=10)
objects = models.Manager()
lawyer_slug = models.SlugField(default='')
def get_absolute_url(self):
return reverse('lawyer_detail', kwargs={'lawyer_slug': self.lawyer_slug})
def __str__(self):
return self.name
class Review(models.Model):
RATING_CHOICES = (
(0, '0'),
(1, '1'),
(2, '2'),
(3, '3'),
(4, '4'),
(5, '5'),
)
lawyer = models.ForeignKey(Lawyer, null=True)
review_created = models.DateTimeField('Date of Review', auto_now_add=True)
reviewer_name = models.CharField(max_length=55, default='')
reviewer_city = models.CharField(max_length=55, default='')
reviewer_state = models.CharField(max_length=2, default='')
email = models.EmailField(default='')
rating = models.IntegerField(default=1, choices=RATING_CHOICES)
review_comment = models.TextField(default='')
review_slug = models.SlugField(default='')
def get_absolute_url(self):
return reverse('lawyer_createreview', kwargs={'review_slug': self.review_slug})
def __str__(self):
return self.review_slug
views.py
class LawyerDetail(DetailView):
model = Lawyer
template = 'lawyer_detail.html'
context_object_name = 'lawyer'
def get_object(self):
lawyer_slug = Lawyer.objects.get(
lawyer_slug=self.kwargs.get('lawyer_slug')
)
return lawyer_slug
def get_context_data(self, **kwargs):
context = super(LawyerDetail, self).get_context_data(**kwargs)
context['lawyer_reviews'] = self.object.review_set.all()
return context
class LawyerReviewCreate(CreateView):
model = Review
form_class = ReviewForm
def get_form_kwargs(self, **kwargs):
kwargs = super(LawyerReviewCreate, self).get_form_kwargs()
redirect = self.request.GET.get('next')
if redirect:
if 'initial' in kwargs.keys():
kwargs['initial'].update({'next': redirect})
else:
kwargs['initial'] = {'next': redirect}
return kwargs
def form_invalid(self, form):
import pdb;pdb.set_trace() # debug example
return super(LawyerReviewCreate, self).form_invalid(form)
def form_valid(self, form):
redirect = form.cleaned_data.get('next')
if redirect:
self.success_url = redirect
return super(LawyerReviewCreate, self).form_valid(form)
urls.py
url(r'^lawyers/(?P<lawyer_slug>[\w-]+)/$', LawyerDetail.as_view(), name='lawyer_detail'),
url(r'^lawyers/(?P<lawyer_slug>[\w-]+)/createreview/$', LawyerReviewCreate.as_view(), name='lawyer_createreview'),
template.html(调用CreateView和显示返回数据的部分)
<div class="review_buttom_wrapper">
<a href="{% url 'lawyer_createreview' lawyer.lawyer_slug %}?next={% url 'lawyer_detail' lawyer.lawyer_slug %}">
<button class="review_button">
<strong>Review</strong> {{ lawyer.name }}
</button>
</a>
</div>
{% for review in lawyer_reviews %}
<div style="padding-left: 15px; padding-right: 15px; overflow:auto;">
<div class="review-masthead">
<div class="medium-3 columns">
<p class="posttime">{{ review.review_created|timesince }} ago </p>
<p class="review-title">{{ review.user_name }} <span class="location">{{ review.lawyer.city }}, {{ review.lawyer.state }}</span></p>
</div>
<div class="medium-7 columns">
<p>{{ review.review_comment }}</p>
</div>
<div class="medium-2 columns">
<div class="user_rating">
Rating
</div>
<div class="rating_number">
{{ review.rating }}
</div>
</div>
</div>
{% endfor %}
forms.py
RATING_CHOICES = (
(1, '1'),
(2, '2'),
(3, '3'),
(4, '4'),
(5, '5'),
)
class ReviewForm(forms.ModelForm):
reviewer_name = forms.CharField(widget = forms.TextInput(attrs={'class': 'review_input_box', 'placeholder': 'Your name'}))
reviewer_city = forms.CharField(widget = forms.TextInput(attrs={'class': 'review_input_box', 'placeholder': 'Your city'}))
reviewer_state = forms.CharField(widget = forms.TextInput(attrs={'class': 'review_input_box', 'placeholder': 'Your state'}))
rating = forms.ChoiceField(choices = RATING_CHOICES, label="", initial='', widget = forms.Select(attrs={'class': 'review_selector'}), required=True)
email = forms.EmailField(widget = forms.TextInput(attrs={'class': 'review_input_box', 'placeholder': 'your-email@email.com'}))
review_comment = forms.CharField(widget = forms.Textarea(attrs={'class': 'review_input_box', 'placeholder': 'What would you like to say?'}))
class Meta:
model = Review
fields = ['reviewer_name', 'reviewer_city', 'reviewer_state', 'rating', 'email', 'review_comment']
Traceback:
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in get_success_url
190. url = self.object.get_absolute_url()
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/ralph/fathers/models.py" in get_absolute_url
142. return reverse('lawyer_createreview', kwargs={'lawyer_slug': self.lawyer_slug})
During handling of the above exception ('Review' object has no attribute 'lawyer_slug'), another exception occurred:
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in post
256. return super(BaseCreateView, self).post(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in post
222. return self.form_valid(form)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/ralph/fathers/views.py" in form_valid
165. return super(LawyerReviewCreate, self).form_valid(form)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in form_valid
202. return super(ModelFormMixin, self).form_valid(form)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in form_valid
108. return HttpResponseRedirect(self.get_success_url())
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in get_success_url
193. "No URL to redirect to. Either provide a url or define"
Exception Type: ImproperlyConfigured at /xxxxxxx/xxxxxxx/xxxxxxx-xxxxxx/createreview/
Exception Value: No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model.
在评论模型
上更改get_absolute_url后的追溯
Traceback:
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/contrib/admin/sites.py" in wrapper
265. return self.admin_view(view, cacheable)(*args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapped_view
149. response = view_func(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
57. response = view_func(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/contrib/admin/sites.py" in inner
244. return view(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/contrib/contenttypes/views.py" in shortcut
31. absurl = get_absolute_url()
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/xxxxx/xxxxxxx/models.py" in get_absolute_url
142. return reverse('lawyer_createreview', kwargs={'review_slug': self.review_slug})
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/urlresolvers.py" in reverse
600. return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/urlresolvers.py" in _reverse_with_prefix
508. (lookup_view_s, args, kwargs, len(patterns), patterns))
Exception Type: NoReverseMatch at /admin/r/14/1/
Exception Value: Reverse for 'lawyer_createreview' with arguments '()' and keyword arguments '{'review_slug': 'michael-ferrin'}' not found. 1 pattern(s) tried: ['fathers/lawyers/(?P<lawyer_slug>[\w-]+)/createreview/$']
执行此操作的最佳方法是在创建视图上添加一个方法 get_success_url
并使用它重定向回详细视图。在创建视图中,您拥有保存后的对象,就像这样
class LawyerReviewCreate(CreateView):
def get_success_url(self):
return reverse('lawyer_detail', kwargs={'lawyer_slug': self.object.lawyer_slug})
如果表单有效,这将自动将用户发送回详细信息视图。
此外,请确保您的 kwargs 使用正确的密钥,在某些情况下您似乎使用 review_slug 而在其他情况下使用 lawyer_slug
我们可以按照 Django 的建议,在我们的模型中添加一个 "get_absolute_url"。它为一个对象设置了一个规范的 URL,所以即使你的 URL 的结构在未来发生变化,对特定对象的引用
是一样的。简而言之,您应该添加一个 get_absolute_url() 方法
你写的每个模型。
def get_absolute_url(self): # new
return reverse('lawyer_detail', args=[str(self.id)])
这应该可以解决您的问题
我正在使用 CreateView 构建表单。 CreateView 是从 DetailView 调用的。提交表单后,我希望将经过验证的提交数据返回到初始 DetailView。
DetailView 调用 CreateView 就好了。表单按预期工作,直到它被提交。然后,我收到此错误:No URL 要重定向到。在模型上提供 url 或定义 get_absolute_url 方法。
我尝试使用
谁能告诉我如何将 CreateView 重定向回原始 DetailView(并传回经过验证的数据?
models.py
class Lawyer(models.Model):
name = models.CharField(max_length=100, default='')
practice_area = models.CharField(max_length=100, default='')
address = models.CharField(max_length=255, default='')
city = models.CharField(max_length=50, default='')
state = models.CharField(max_length=2, default='')
zipcode = models.CharField(max_length=10, default='')
telephone = models.CharField(max_length=15, default='')
years_practice = models.IntegerField(default=10)
objects = models.Manager()
lawyer_slug = models.SlugField(default='')
def get_absolute_url(self):
return reverse('lawyer_detail', kwargs={'lawyer_slug': self.lawyer_slug})
def __str__(self):
return self.name
class Review(models.Model):
RATING_CHOICES = (
(0, '0'),
(1, '1'),
(2, '2'),
(3, '3'),
(4, '4'),
(5, '5'),
)
lawyer = models.ForeignKey(Lawyer, null=True)
review_created = models.DateTimeField('Date of Review', auto_now_add=True)
reviewer_name = models.CharField(max_length=55, default='')
reviewer_city = models.CharField(max_length=55, default='')
reviewer_state = models.CharField(max_length=2, default='')
email = models.EmailField(default='')
rating = models.IntegerField(default=1, choices=RATING_CHOICES)
review_comment = models.TextField(default='')
review_slug = models.SlugField(default='')
def get_absolute_url(self):
return reverse('lawyer_createreview', kwargs={'review_slug': self.review_slug})
def __str__(self):
return self.review_slug
views.py
class LawyerDetail(DetailView):
model = Lawyer
template = 'lawyer_detail.html'
context_object_name = 'lawyer'
def get_object(self):
lawyer_slug = Lawyer.objects.get(
lawyer_slug=self.kwargs.get('lawyer_slug')
)
return lawyer_slug
def get_context_data(self, **kwargs):
context = super(LawyerDetail, self).get_context_data(**kwargs)
context['lawyer_reviews'] = self.object.review_set.all()
return context
class LawyerReviewCreate(CreateView):
model = Review
form_class = ReviewForm
def get_form_kwargs(self, **kwargs):
kwargs = super(LawyerReviewCreate, self).get_form_kwargs()
redirect = self.request.GET.get('next')
if redirect:
if 'initial' in kwargs.keys():
kwargs['initial'].update({'next': redirect})
else:
kwargs['initial'] = {'next': redirect}
return kwargs
def form_invalid(self, form):
import pdb;pdb.set_trace() # debug example
return super(LawyerReviewCreate, self).form_invalid(form)
def form_valid(self, form):
redirect = form.cleaned_data.get('next')
if redirect:
self.success_url = redirect
return super(LawyerReviewCreate, self).form_valid(form)
urls.py
url(r'^lawyers/(?P<lawyer_slug>[\w-]+)/$', LawyerDetail.as_view(), name='lawyer_detail'),
url(r'^lawyers/(?P<lawyer_slug>[\w-]+)/createreview/$', LawyerReviewCreate.as_view(), name='lawyer_createreview'),
template.html(调用CreateView和显示返回数据的部分)
<div class="review_buttom_wrapper">
<a href="{% url 'lawyer_createreview' lawyer.lawyer_slug %}?next={% url 'lawyer_detail' lawyer.lawyer_slug %}">
<button class="review_button">
<strong>Review</strong> {{ lawyer.name }}
</button>
</a>
</div>
{% for review in lawyer_reviews %}
<div style="padding-left: 15px; padding-right: 15px; overflow:auto;">
<div class="review-masthead">
<div class="medium-3 columns">
<p class="posttime">{{ review.review_created|timesince }} ago </p>
<p class="review-title">{{ review.user_name }} <span class="location">{{ review.lawyer.city }}, {{ review.lawyer.state }}</span></p>
</div>
<div class="medium-7 columns">
<p>{{ review.review_comment }}</p>
</div>
<div class="medium-2 columns">
<div class="user_rating">
Rating
</div>
<div class="rating_number">
{{ review.rating }}
</div>
</div>
</div>
{% endfor %}
forms.py
RATING_CHOICES = (
(1, '1'),
(2, '2'),
(3, '3'),
(4, '4'),
(5, '5'),
)
class ReviewForm(forms.ModelForm):
reviewer_name = forms.CharField(widget = forms.TextInput(attrs={'class': 'review_input_box', 'placeholder': 'Your name'}))
reviewer_city = forms.CharField(widget = forms.TextInput(attrs={'class': 'review_input_box', 'placeholder': 'Your city'}))
reviewer_state = forms.CharField(widget = forms.TextInput(attrs={'class': 'review_input_box', 'placeholder': 'Your state'}))
rating = forms.ChoiceField(choices = RATING_CHOICES, label="", initial='', widget = forms.Select(attrs={'class': 'review_selector'}), required=True)
email = forms.EmailField(widget = forms.TextInput(attrs={'class': 'review_input_box', 'placeholder': 'your-email@email.com'}))
review_comment = forms.CharField(widget = forms.Textarea(attrs={'class': 'review_input_box', 'placeholder': 'What would you like to say?'}))
class Meta:
model = Review
fields = ['reviewer_name', 'reviewer_city', 'reviewer_state', 'rating', 'email', 'review_comment']
Traceback:
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in get_success_url
190. url = self.object.get_absolute_url()
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/ralph/fathers/models.py" in get_absolute_url
142. return reverse('lawyer_createreview', kwargs={'lawyer_slug': self.lawyer_slug})
During handling of the above exception ('Review' object has no attribute 'lawyer_slug'), another exception occurred:
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/base.py" in view
68. return self.dispatch(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/base.py" in dispatch
88. return handler(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in post
256. return super(BaseCreateView, self).post(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in post
222. return self.form_valid(form)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/ralph/fathers/views.py" in form_valid
165. return super(LawyerReviewCreate, self).form_valid(form)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in form_valid
202. return super(ModelFormMixin, self).form_valid(form)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in form_valid
108. return HttpResponseRedirect(self.get_success_url())
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/generic/edit.py" in get_success_url
193. "No URL to redirect to. Either provide a url or define"
Exception Type: ImproperlyConfigured at /xxxxxxx/xxxxxxx/xxxxxxx-xxxxxx/createreview/
Exception Value: No URL to redirect to. Either provide a url or define a get_absolute_url method on the Model.
在评论模型
上更改get_absolute_url后的追溯Traceback:
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
149. response = self.process_exception_by_middleware(e, request)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/handlers/base.py" in get_response
147. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/contrib/admin/sites.py" in wrapper
265. return self.admin_view(view, cacheable)(*args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/utils/decorators.py" in _wrapped_view
149. response = view_func(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
57. response = view_func(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/contrib/admin/sites.py" in inner
244. return view(request, *args, **kwargs)
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/contrib/contenttypes/views.py" in shortcut
31. absurl = get_absolute_url()
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/xxxxx/xxxxxxx/models.py" in get_absolute_url
142. return reverse('lawyer_createreview', kwargs={'review_slug': self.review_slug})
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/urlresolvers.py" in reverse
600. return force_text(iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs)))
File "/xxxx/xxxxxxxxxx/xxxx/xxxxxxxxxxxx/lib/python3.5/site-packages/django/core/urlresolvers.py" in _reverse_with_prefix
508. (lookup_view_s, args, kwargs, len(patterns), patterns))
Exception Type: NoReverseMatch at /admin/r/14/1/
Exception Value: Reverse for 'lawyer_createreview' with arguments '()' and keyword arguments '{'review_slug': 'michael-ferrin'}' not found. 1 pattern(s) tried: ['fathers/lawyers/(?P<lawyer_slug>[\w-]+)/createreview/$']
执行此操作的最佳方法是在创建视图上添加一个方法 get_success_url
并使用它重定向回详细视图。在创建视图中,您拥有保存后的对象,就像这样
class LawyerReviewCreate(CreateView):
def get_success_url(self):
return reverse('lawyer_detail', kwargs={'lawyer_slug': self.object.lawyer_slug})
如果表单有效,这将自动将用户发送回详细信息视图。
此外,请确保您的 kwargs 使用正确的密钥,在某些情况下您似乎使用 review_slug 而在其他情况下使用 lawyer_slug
我们可以按照 Django 的建议,在我们的模型中添加一个 "get_absolute_url"。它为一个对象设置了一个规范的 URL,所以即使你的 URL 的结构在未来发生变化,对特定对象的引用 是一样的。简而言之,您应该添加一个 get_absolute_url() 方法 你写的每个模型。
def get_absolute_url(self): # new
return reverse('lawyer_detail', args=[str(self.id)])
这应该可以解决您的问题