2012-05-05 10 views
6

Django-MPTTアプリケーションを使用して、Djangoサイトのページでツリーベースのアプローチを開始します。Django-MPTT子ページへのフルパス作成方法?

例:私は、サブページとページを持っている:

トランス:

  • ボーカルトランス(サブページ)
  • ハードトランス(サブページ)

ブレイク:

  • ATMO改(サブページ)
  • プログレッシブブレイク(サブページ)

どうすればurls.pyからアクセスできますか? どのようなパターンが役に立ちますか? モデルにFull_pathを格納する必要がありますか?それともurlパターンで行うことができますか?

答えて

7

私はあなたがこのようなURLをしたいわけ前提としています

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

もしそうなら、それはあなたのモデルにURLフラグメントを保存するために、おそらく最善です。ような何か:

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's 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's 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) 

そして、URLパターンを追加:

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

をそして、あなたのビューであなただけの右のページをフェッチすることができます

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

あなたがルート/枝スラグを変更し、子孫のURLを更新する必要がある場合はどうですか? – jozxyqk

6

は私の問題へのご清聴ありがとうございました。 参照してください、私は最終的にどのようにそれを行う。トリックは、私たちにある

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's 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)) 

は、ページが実際に存在するかどうかを確認する必要がありますfull_slug経由でアクセス:

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

それ以外の場合は、スラッグのみで確認することができない可能性があります。

+0

この機能を持つCRUDを置くための+1 .. – Soask

2

あなたのための作業を行いますDjangoのアプリもあります:django-mptt-urls

+0

はい、 'a app'を 'django app'に置き換えることは本当に正しい編集です! Anatoly techtonik、今あなたと@ Forethinkerで祈っています – MrKsn

0
def get_absolute_url(self): 
    return '/'.join([x['slug'] for x in self.get_ancestors(include_self=True).values()]) 
関連する問題