Tags:
Forums: 

หลังจากเริ่ม code django ไปได้พอสมควร ผมพบมีปัญหาเกี่ยวกับ Template ซึ่งดูแล้วมันขัดแย้งกับ concept DRY(Don't Repeat Yourself) ชอบกล

ผมวาง structure ของ Template ไว้ประมาณนี้นะครับ

base.html

{% include "auth.html" %}

{% block content %}
{% end block %}

auth.html

{% ifequal user None %}
{% include "auth/signin.html" %}
<a href="/signup">Sign Up</a>
{% else %}
{{ user.email }}
<a href="/signout">Sign Out</a>
{% endifequal %}

singin.html

<form action="/signin/" method="post">
{{ signInForm.as_p }}
<input type="submit" value="Submit" />
</form>

ปัญหาคือพอเริ่ม implement หลาย page มากขึ้น ในทุกๆ view ของผม ผมต้อง Repeat code เกี่ยวกับ user เสมอ เช็คว่า login รึยัง ถ้ายังก็ต้องส่ง signInForm มาให้ template

มันน่าจะมีวิธีที่จะ call signInForm จากตัว Template หรือใครมีวิธีอื่นในการแก้ปัญหาแบบนี้มั๊ยครับ

Get latest news from Blognone
By: sirn
WriteriPhone
on 20 February 2010 - 19:56 #158684

ถ้าอ่านคำถามไม่ผิด เหมือนคุณจะต้องการทำ form login ในทุกหน้าถ้า user ไม่ได้ login แต่ไม่อยากจะ pass signInForm ทุกครั้งใช่ไหมครับ ถ้าเป็นแบบนั้นขอแนะนำให้ใช้ inclusion tag ครับ

วิธีใช้ก็ราวๆ นี้

สร้างไฟล์ app/templatetags/login.py หน้าตาประมาณ

from django import template
from project.app.forms import LoginForm

register = template.Library()

@register.inclusion_tag('inclusions/login_form.html')
def show_user_or_login(user):
    form = None
    if not user.is_logged_in():
        form = Login()
    return {'user':user, 'form':form}

สร้าง template ที่ templates/inclusions/login_form.html (ทำไม prefix 4 spaces แล้วมันไม่ยอม escape form ให้เนี่ย)

{% if form %}
{{ form.as_p }}
<a href="/register/">Register</a>
{% else %}
<a href="/logout/">Logout</a>
{% endif %}

แล้วเวลาเรียกใช้ก็เช่น base.html

{% load login %}
{% show_user_or_login user %}

เจ้า variable user เนี่ย มันจะส่งไปให้ template ต่อเมื่อใช้ RequestContext เท่านั้น ระวังไว้ให้ดี

น่าจะตรงตามที่ต้องการนะครับ

By: Bluegear on 20 February 2010 - 23:22 #158701
Bluegear's picture

ขอบคุณครับ ก็คิดอยู่เหมือนกันว่าน่าจะต้องสร้าง custom tag จริงๆ จะลองทำตามคำแนะนำ แล้วมาบอกผลนะครับ ^^

By: Bluegear on 20 February 2010 - 23:35 #158703
Bluegear's picture

ปรากฎว่าใช้ได้ผล! ขอบคุณมากครับ :)

By: JackSW
Android
on 22 February 2010 - 23:10 #158926
JackSW's picture

ผมทำไม่ได้ครับ ไม่รู้ว่าวางไฟล์ไม่ถูกที่หรือเปล่า

ผมว่างไฟล์แบบนี้

ไฟล์ check_login.py from django import template register = template.Library() @register.inclusion_tag('login_or_user.html') def show_user_or_login(user):     logged_in = user.is_logged_in()     return {'logged_in':logged_in} แล้วก็ base.html ... {% load check_login %} {% show_user_or_login user %} ... ผมหาดูตัวอย่างบางที่ก็ไม่มี {% load %} นะครับ ไม่รู้ว่าใช้สาเหตุหรือเปล่า

ขอบคุณครับ

By: sirn
WriteriPhone
on 23 February 2010 - 14:44 #158997

Directory แบบนั้นต้องใช้ @register.inclusion_tag('inclusion/login_or_user.html') ครับ

By: thanatrakul
iPhoneWindows PhoneAndroidBlackberry
on 26 September 2012 - 22:21 #481013

@login_require
def xxxx():
....