Django-MPTT full path to child pages, how to do?

I am starting to use the Django-MPTT application to get a tree view on my Django site pages.

For example, I have pages with additional pages:

Trance:

  • Vocal Trance (subpage)
  • Hard Trance (subpage)

Breaks:

  • Atmo Breaks (subpage)
  • Progressive breaks (sub page)

How can I access them from urls.py? Which template will help? Is it necessary to store Full_path in the model, or can this be done using the url template?

+6
source share
4 answers

I assume that you want you to do the following URLs:

/trance/ /trance/vocal-trance/ /trance/hard-trace/ /breaks/ /breaks/atmo-breaks/ /breaks/progressive-breaks/ 

If so, it is probably best to keep the url fragment in your model. Sort of:

 from mptt.models import MPTTModel from django.db import models from django.template.defaultfilters import slugify class Page(MPTTModel): name = models.CharField(max_length=50) slug = models.CharField(max_length=50,null=True) url = models.CharField(max_length=255,null=True) def save(self, *args, **kwargs) if self.slug is None: # create a slug that unique to siblings slug = slugify(self.name) self.slug = slug siblings = self.get_siblings() i = 1 while siblings.filter(slug=self.slug).exists(): i += 1 self.slug = slug + '-%d' % i # now create a URL based on parent url + slug if self.parent: self.url = '%s/%s' % (self.parent.url, self.slug) else: self.url = self.slug super(Page, self).save(*args, **kwargs) 

Then add the URL pattern:

 (r'^pages/(?P<page_url>[\w\d_/-]+)/$', 'pages.views.show_page'), 

And, in your opinion, you can simply select the desired page:

 def show_page(request, page_url=None): page = get_object_or_404(Page, url=page_url) ... 
+7
source

Thank you for your attention to my problem. Watch me finally do it.

models.py

 class WebPage(MPTTModel): slug=RuSlugField(max_length=20,unique=True) title=models.CharField(max_length=50) content=models.TextField() parent=TreeForeignKey('self',null=True,blank=True,related_name='children') class MPTTMeta: order_insertion_by=['slug'] def get_absolute_url(self):#TODO:: replace with get_ancestors url = "/%s/" % self.slug page = self while page.parent: url = "/%s%s" % (page.parent.slug,url) page = page.parent return url 

urls.py

 urlpatterns = patterns('website.views', url(r"^add/$", "add_page",name="add"), url(r"^(?P<full_slug>.*)/add/$", "add_page",name="add"), url(r"^(?P<full_slug>.*)/edit/$", "edit_page",name="edit"), url(r'^$', ListView.as_view(model=WebPage,template_name='index.html',context_object_name="webpages_list",),name='index'), url(r"^(?P<full_slug>.*)/$", "page", name="page"), ) 

views.py

 def page(request, full_slug): # Make a list from full_slug. # For ex. /trance/progressive_trance/fonarev -> ['trance','progressive_trance','fonarev'] slugs=full_slug.split('/') page=None # Get a page by it slug if len(slugs)>1: page=get_object_or_404(WebPage,slug=slugs[-1])#slugs=['trance','vocal_trance'] -> 'vocal_trance' elif len(slugs)==1: page=get_object_or_404(WebPage,slug=slugs[0])#slugs=['trance'] -> 'trance' # Check if page url matches requested full_slug if page.get_absolute_url().strip('/') == full_slug: return render_to_response('page.html', {'page': page},context_instance=RequestContext(request)) else: raise Http404 def edit_page(request,full_slug): slugs=full_slug.split('/') page=None if len(slugs)>1: page=get_object_or_404(WebPage,slug=slugs[-1]) elif len(slugs)==1: page=get_object_or_404(WebPage,slug=slugs[0]) if not page.get_absolute_url().strip('/') == full_slug: raise Http404 # Send POST data for update an existing page.Update a page. if request.method=='POST': form=WebPageForm(request.POST, instance=page) if form.is_valid(): form.save() return HttpResponseRedirect(page.get_absolute_url()) # Render a form to edit data for existing page else: form=WebPageForm(instance=page) return render_to_response('edit_page.html',{'form':form,},context_instance=RequestContext(request)) def add_page(request,full_slug=None): parent_page=None slug=None if full_slug: slug=full_slug.split('/') # If there is a slug in REQUEST(ex.'trance')->we need to add a new_page to her parent_page. # So get a parent page. if slug: if len(slug)>1: parent_page=get_object_or_404(WebPage,slug=slug[-1]) elif len(slug)==1: parent_page=get_object_or_404(WebPage,slug=slug[0]) # Create a new_page if request.method=='POST': form=WebPageForm(request.POST) if form.is_valid(): new_page=form.save(commit=False) if parent_page: new_page.parent=parent_page new_page.save() return HttpResponseRedirect(new_page.get_absolute_url()) # Return an unbounded form else: form=WebPageForm() return render_to_response('add_page.html',{'form':form,},context_instance=RequestContext(request)) 

The trick is that we need to check if the page really has access to it through full_slug:

 if not page.get_absolute_url().strip('/') == full_slug: raise Http404 

Otherwise, it may be wrong if you can only check bullets.

+6
source

There is also a django application that will do the work for you: django-mptt-urls

+2
source
 def get_absolute_url(self): return '/'.join([x['slug'] for x in self.get_ancestors(include_self=True).values()]) 
0
source

Source: https://habr.com/ru/post/914957/


All Articles