2013-03-19 3 views
4

Flask에서 작동하는 아주 단순한 사이트가 있는데이 사이트는 모두 sqlite db로 구동됩니다. 각 페이지는 경로, 제목, 내용과 같은 항목을 포함하는 페이지 테이블의 행으로 저장됩니다.Flask의 동적 탐색

구조는 페이지에 상위가있을 수있는 계층 구조입니다. 예를 들어 'about'은 페이지 일 수 있지만 'about/something'과 'about/cakes'가있을 수도 있습니다. 그래서 '/'(/는 루트 페이지)의 부모를 가진 모든 링크에 대한 링크가 포함 된 탐색 모음을 만들려고합니다. 또한 열려있는 페이지와 해당 페이지의 모든 부모를 표시하는 것이 좋습니다.

예를 들어 우리가 'about/cakes/muffins'에있는 경우 항상 표시되는 링크 외에도 'about/cakes'에 대한 링크가 다음과 같이 표시됩니다.

- About/ 
    - Cakes/ 
    - Muffins 
    - Genoise 
    - Pies/ 
- Stuff/ 
- Contact 
- Legal 
- Etc.[/] 

자녀가있는 페이지에는 슬래시를 사용하고 그렇지 않은 페이지에는 슬래시를 사용하십시오.

코드 :

@app.route('/') 
def index(): 
    page = query_db('select * from page where path = "/"', one=True) 
    return render_template('page.html', page=page, bread=['']) 

@app.route('/<path>') 
def page(path=None): 
    page = query_db('select * from page where path = "%s"' % path, one=True) 
    bread = Bread(path) 
    return render_template('page.html', page=page, crumbs=bread.links) 

내가 거기에 두 가지 기능을 가진 드라이을 위반 한 것 같은 나는 이미 생각합니다. 그러나 네비게이션을 수행하면 오류 페이지와 같은 항목에 대한 탐색을 원하므로 추가로 위반하게됩니다.

그러나 나는 이것을 수행하기위한 특히 Flasky 방법을 찾을 수 없습니다. 어떤 아이디어?

+2

죄송합니다. 귀하가 여기서 무엇을 묻고 있는지 정확히 모르겠습니다. 정확히 어떻게해야합니까? '페이지'뷰에서 SQL 쿼리를 작성하는 방식은 안전하지 않으며 주입 공격에 개방적입니다. 사용자 입력을 안전하게 처리하는 방법을 보려면 [여기] (http://stackoverflow.com/a/775399/1949092)의 몇 가지 답변을 살펴보십시오. – DazWorrall

+0

예, 모든 임시 코드입니다. SQL 주입에 대해 알고 있습니다. Flask에서 동적 트리 탐색을 수행하는 방법을 묻습니다. mppt를 사용하여 django에서이 작업을 수행했지만 Flask가 어디에서도 동등하지는 않습니다. –

+0

비슷한 질문이 있지만 내비게이션을 flask.session 변수에 액세스해야합니다. https://stackoverflow.com/questions/45948609/accessing-flask-session-variables-from-flask-navigation-for-dynamic-navigation-m –

답변

5

은 "flasky"와 파이썬 방법은 클래스 기반보기 및 템플릿 계층 구조를 사용하는 것입니다

모든

먼저, 당신은이 방법을 기반으로 코드를 리팩토링 할 수 모두에서 문서를 읽어

다음
class MainPage(MethodView): 
    navigation=False 
    context={} 

    def prepare(self,*args,**kwargs): 
     if self.navigation: 
      self.context['navigation']={ 
       #building navigation 
       #in your case based on request.args.get('page') 
      } 
     else: 
      self.context['navigation']=None 

    def dispatch_request(self, *args, **kwargs): 
     self.context=dict() #should nullify context on request, since Views classes objects are shared between requests 
     self.prepare(self,*args,**kwargs) 
     return super(MainPage,self).dispatch_request(*args,**kwargs) 

class PageWithNavigation(MainPage): 
    navigation = True 

class ContentPage(PageWithNavigation): 
    def get(self): 
     page={} #here you do your magic to get page data 
     self.context['page']=page 
     #self.context['bread']=bread 
     #self.context['something_Else']=something_Else 
     return render_template('page.html',**self.context) 

당신이 다음을 수행 할 수 main_를 들어, 별도의 페이지를 만들 page.html 및 page_with_navigation.html 그런 다음 각 페이지 "error.html, page.html, somethingelse.html"중 하나를 기반으로합니다.

def prepare(self): 
     if self.navigation: 
      self.context['navigation']={ 
       #building navigation 
       #in your case based on request.args.get('page') 
      } 
     else: 
      self.context['navigation']=None 
     #added another if to point on changes, but you can combine with previous one 
     if self.navigation: 
      self.context['extends_with']="templates/page_with_navigation.html" 
     else: 
      self.context['extends_with']="templates/main_page.html" 

그리고 템플릿 :

하는 방법을 조금 준비 수정합니다 : 의 핵심은 동적으로이 작업을 수행하는 것입니다 main_page.html을

<!DOCTYPE html> 
<html> 
<head> 
    <title></title> 
</head> 
<body> 
    {% block navigation %} 
    {% endblock %} 
    {% block main_content %} 
    {% endblock %} 
</body> 
</html> 

page_with_navigation.html

{% extends "/templates/main_page.html" %} 

{% block navigation %} 
     here you build your navigation based on navigation context variable, which already passed in here 
{% endblock %} 

page.html 또는 기타 some_page.html. 계속 간단하게!
첫 줄에주의하십시오. 보기가 어느 페이지에 들어가야하는지 설정하고 navigation = of view-class를 설정하여 쉽게 조정할 수 있습니다.

{% extends extends_with %} 

{% block main_content %} 
     So this is your end-game page. 
     Yo do not worry here about navigation, all this things must be set in view class and template should not worry about them 
     But in case you need them they still available in navigation context variable 
{% endblock %} 
2

당신은 가진 여러 장식으로 하나의 함수에서 작업을 수행 할 수 있습니다 :

@app.route('/', defaults={'path': '/'}) 
@app.route('/<path>') 
def page(path): 
    page = query_db('select * from page where path = "%s"' % path, one=True) 
    if path == '/': 
     bread = Bread(path) 
     crumbs = bread.links 
    else: 
     bread = [''] 
     crumbs = None 
    return render_template('page.html', page=page, bread=bread, crumbs=crumbs) 

개인적으로 나는 또한 비록 경로 / 일하기 빵 기능을 수정하는 것입니다. 그것이 내가 상황에 맞는 프로세서를 찾고 추천 할 것보다, 당신의 상황에 변수를 추가하는 방법에 대해 간단하게라면

: http://flask.pocoo.org/docs/templating/#context-processors

+0

내가 관심있어하는 빵 부스러기는 아니지만 그 작품은 이미 있습니다. 나는 그 나머지 항해를 끝내고 일한다. –

+0

@Knyght : 컨텍스트 프로세서에 대한 부분을 보았습니까? 그것들은 너를 위해 이걸 멋지게 고칠 수 있어야한다. 약간의 컨텍스트 프로세서를 작성하여 지정된 경로 (또는 요청)를 기반으로 탐색 메뉴를 자동으로 생성하면 제대로 작동합니다. – Wolph

+0

또한 wooops, 나는 bread()이 얼마 전에 작동하는 방식을 바꾸었고, 스스로를 반복 할 때 얻을 수있는 첫 번째 함수를 업데이트하는 것을 잊었다. 여러 데코레이터 팁 주셔서 감사합니다. 그리고 컨텍스트 프로세서를 살펴 보겠습니다. 감사. –