Wagtail route still returns 404 - python

I encountered a bit weird problem and not really sure why it happens.
This is my model:
class PostIndexPage(RoutablePage):
max_count = 1
parent_page_types = []
intro = RichTextField(blank=True)
content_panels = Page.content_panels + [
FieldPanel('intro', classname="full")
]
#route(r'^posts/$')
def main(self, request):
from django.shortcuts import render
return render(request, self.get_template(request), self.get_context(request))
I defined route in that model but it seems to have no effect.
http://127.0.0.1:8000/post-index-page/ - the old url is still working the old way
http://127.0.0.1:8000/posts/ - but this one doesn't (404, not found).
Do you have any idea what I'm doing wrong?

URL routes defined by #route on a RoutablePage are relative to the normal path of the page, as determined by its slug and position in the page tree. If you created a routable page with the slug post-index-page, the posts route will be found at /post-index-page/posts/.
If you want a view that remains at a completely fixed URL, you can always define that as a standard Django view.

Related

Django redirect_url with parameter

I have a simple UpdateView which updates instances of my Profile model.
class ProfileUpdateView(UpdateView):
model = Profile
fields = ['first_name', 'last_name']
It's working fine both GET and POST, but since the GET uses an url parameter, I want also the redirect_url to redirect to the updated profile.
My current urls.py:
from profiles.views import ProfileUpdateView
urlpatterns = [
path('self/<slug:slug>', ProfileUpdateView.as_view(success_url='/'), name='self_profile')
]
It is currently redirecting to the main url, but I don't figure out how to make the redirect_url parameter redirect to the profile modified on the handled POST.
Let's say I do http://localhost:8000/profiles/self/demo, (GET), then I modify my first_name and submit the request. I want the redirection to go to /profiles/self/demo again.
I know I could override def post() on the view and achieve it, but since I only want to deal with the redirection I wanted to know if exists any other elegant solution.
EDIT:
Additional info: the slug url parameter will always be request.user in this case (since I use other view (a DetailView) to see other users' profiles).
Thanks!!
Override the get_success_url(...) method as
class ProfileUpdateView(UpdateView):
model = Profile
fields = ['first_name', 'last_name']
def get_success_url(self):
return '/profiles/self/demo'
Hence, you don't need to specify the success_url attribute in the urls.py
from profiles.views import ProfileUpdateView
urlpatterns = [
path('self/<slug:slug>', ProfileUpdateView.as_view(), name='self_profile')
]

Django 2.0 UpdateView NoReverseMatch

PLEASE IGNORE!
Trying to use UpdateView to update a model object with name "Tag"
Here is the model:
NAME_REGEX = r'^[a-zA-Z0-9\s.\-]+$'
class Tag(TimeStampModel):
name = models.CharField(max_length=40,
validators = [
RegexValidator(regex=NAME_REGEX,
message='name must be alphanumeric, may contain - _',
code='invalid tag name')],
unique=True)
slug = models.SlugField(max_length=60, unique=True, blank=True)
text = models.TextField(blank=True)
def __str__(self):
return self.name
def get_absolute_url(self):
url = reverse('tags:tag_detail', kwargs={'slug':self.slug})
print('Tag *************** 010 ********************')
print(url)
return url
def save(self, *args, **kwargs):
self.slug = make_slug(self.name)
super().save()
I am able to create a Tag using CreateView, list the Tags using ListView and access the Tag detail using DetailView. I am also able to edit the tag using a function based view. However, it falls down with UpdateView.
Here are the urls:
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('tag_list/', views.TagListView.as_view(), name='tag_list'),
path('tag_detail/<slug:slug>/', views.TagDetailView.as_view(),
name='tag_detail'),
path('create_tag/', views.CreateTagView.as_view(),
name = 'create_tag'),
path('update_tag/<slug:slug>/', views.UpdateTagView.as_view(),
name = 'update_tag'),
path('category_list/', views.CategoryListView.as_view(),
name = 'category_list'),
path('category_detail/<slug>/', views.CategoryDetailView.as_view(),
name = 'category_detail'),
]
In a template called "tag_detail.html" I provide a link that should take the user to an edit form as follows:
<p class="slm-red">
{{ tag_dict.slug }}
<br>
Edit Tag
</p>
(I've printed the value of the slug before the link. That is not the problem. The slug value is correct. in this case slug = "brown")
When I click the link it takes me to:
http://localhost:8000/tags/update_tag/brown/
In this case the slug has the value "brown"
I get the following error message:
Reverse for 'update_tag' with no arguments not found. 1 pattern(s) tried: ['tags\\/update_tag\\/(?P<slug>[-a-zA-Z0-9_]+)\\/$']
I tried it the old fashioned way using "url" instead of path and a regular expression for the slug with the same result.
It all works fine when I use a function based view passing slug as a parameter.
Here is the UpdateTagView:
class UpdateTagView(UpdateView):
print('UpdateTagView ************** 010 *****************')
template_name = 'tags/update_tag.html'
model = Tag
fields = ['text']
The first line is a print statement. It does not appear on the console log so this confirms that Django never gets as far as the actual view. What I do get on the console log includes the following:
[22/Jan/2018 16:06:00] "GET /tags/tag_detail/brown/ HTTP/1.1" 200 4852
Internal Server Error: /tags/update_tag/brown/
I've tried several variants but nothing works. I am getting quite desperate.
I've seen similar questions on stack overflow for previous versions of Django but there never seems to be an answer.
When I use an FBV it's simple. I just pass the slug as a parameter along with request.
For what it's worth the errors seems to be occurring in base.py. At the end of the error messages I see:
C:\django\_dj\projenv\lib\site-packages\django\urls\base.py in reverse
I think there's a kwarg I'm supposed to override but I have no notion how to do it. Since Django never gets as far as the UpdateTagView nothing I do there can affect the outcome.

Django redirecting url with changed values

I have urls that take a parameter called board_slug. Before getting the template the view will replace the slug if its name is wrong and redirect it. I have already made the code for fixing the slug but do not know how insert the fixed board_slug into the new url. This code is run across multiple views so it has to work with all the following kinds urls:
url(r'^boards/(?P<board_slug>[^/]+)/$', views.BoardView.as_view(), name='board'),
url(r'^/front-thing/boards/(?P<board_slug>[^/]+)/new/$', views.BoardView.as_view(), name='new_board'),
url(r'^boards/(?P<board_slug>[^/]+)/etc...$', views.BoardView.as_view(), name='anything_with_board'),
class BoardView(View):
template_name = 'forums/board.html'
def get(self, request, board_slug):
if wrong:
url = get_django_url
url.board_slug = 'new-slug'
return redirect(url)
else:
return template

Django admin - add custom link to change list view

Firstly thanks for taking the time to read my problem
I tried to add a custom button to my admin changeList view, but it always gives me Page not found (404)
This my modelAdmin code:
class MyModelAdmin(admin.ModelAdmin):
class Media:
js = ('admin/js/additional_js.js',)
model = MyModel
def get_urls(self):
urls = super(MyModelAdmin, self).get_urls()
analyze_url = patterns('',
(r'^(?P<pk>\d+)/analyze/$',
self.admin_site.admin_view(self.analyze_view))
)
return analyze_url + urls
def analyze_view(self, request, pk):
# some code here
HttpResponseRedirect(
reverse('admin:myapp_MyModel_change', args=(pk,))
)
My jQuery code for adding custom link to change list view:
(function($) {
$(document).ready(function($) {
$(".object-tools").append('<li>Analyze</li>');
});
})(django.jQuery);
when I click my custom link it gives me this:
MyModel object with primary key '3/change/analyze' does not exist.
I see that the link does not point to the view
Can someone help me fix this issue.
Thanks
In Django 1.9, the admin change url has changed to /admin/<app>/<model>/<pk>/change/ (release notes).
Therefore, it doesn't make sense to link to href="analyze/" in your html. The relative url is treated as /admin/<app>/<model>/3/change/analyze, not /admin/<app>/<model>/3/analyze as you expect.
You can probably fix the problem by changing the link to:
<a href="../analyze/" ...
Ideally, it would be better to reverse the url rather than having a relative link. I think this would make the code less fragile.
Since you are using Django 1.9, you can update your code to use a list rather than patterns:
from django.conf.urls import url
analyze_url = [
url(r'^(?P<pk>\d+)/analyze/$', self.admin_site.admin_view(self.analyze_view)),
]

Django Admin Custom View URL not being recognized

I am using Django 1.8 on Python 3.4.3
I have a Model called FormUpload and I am adding a ModelAdmin for the same in admins.py in the same application "mca".
#admin.register(FormUpload)
class FormUploadAdmin(admin.ModelAdmin):
def upload_form(self, request):
context = dict(
# Include common variables for rendering the admin template.
self.admin_site.each_context(request),
# Anything else we want in the context...
)
return TemplateResponse(request, "admin/formupload.html", context)
def get_urls(self):
urls = super(FormUploadAdmin, self).get_urls()
upload_admin_urls = [
url(r'^upload/$', self.admin_site.admin_view(self.upload_form)),
]
logger.debug(upload_admin_urls)
return upload_admin_urls + urls
This should have been available at /admin/mca/upload/ . However when I go the URL I get a 404 saying the current URL doesn't match anything
Here is the output of the debug
RegexURLPattern None ^upload/$
(Removed few things that will make the display weird for the debug).
Please notice the None. If the other URLs are listed out there is a method name where the None is.
What am I doing wrong here ? I am following the approach suggested in django documentation - https://docs.djangoproject.com/en/1.8/ref/contrib/admin/#modeladmin-methods

Categories