Django Framework Template Etiketlerinde User Objesine Erişmek

Share Button

Aslında django kullanıcıları için muhtemelen çok basit bir konu ancak benim gibi yeni başlayanlar için sorun olabilecek konulardan biri olduğu için yazıyı sizinle paylaşmak istedim.

Problem:
Django öğrenmek için yazdığım blog projesinde kullanıcıya gösterdiğim blog postunun yeni comment girişi alanını, comment blog postuna veya başka bir comment e yanıt olarak girilebileceğinden inclusion_tag yaptım. Ancak inclusion tag in include ettiği template içinde user objesine ulaşamıyorum.

Çözüm:
Uzun stackoverflow okumlarından sonra inclusion_tag e parametre olarak takes_context göndersem de tag e parametre olarak gelen context içinde user objesinin gelmediğini öğrendim. Bunun yerine view tarafında, ilgili actionda return edilen render fonksiyonuna parametre olarak, context_instance için RequestContext göndermem gerekiyormuş. Böyle olunca tag e parametre olarak gelen context içinde user objesinin yeraldığını gördüm.

Problemi çözmek için aşağıdaki adımları uyguladım:

1. view tarafında django.template içindeki RequestContext objesini import ettim.
myapp/views.py:

from django.template import RequestContext

2. İlgili template tag i kullanacağım view ın aksiyonunda return ettiğim render() fonksiyonuna context_instance olarak RequestContext i gönderdim.
myapp/views.py:

def viewpost(request, post_id):
    post = get_object_or_404(Post.objects.select_related('author'), pk=post_id)
    ...
    return render(
        request, 'blog/post/detail.html', 
        {'post' : post}, 
        context_instance=RequestContext(request)
    )

3. template tag tarafında include edeceğim template e veri olarak user objesini gönderdim.
myapp/templatetags/myapp_extra.py:

@register.inclusion_tag('blog/post/blocks/comment/new.html', takes_context=True)
def show_comment_input(context):
    return {'user' : context['user']}

4. Ve… template tag imin include ettiği template kodu.
blog/post/blocks/comment/new.html:

<form action="#" method="POST" class="well" style="margin:0px">
    <h3>Write your comment or reply</h3>

    {% if not user.is_authenticated %}
    <div class="controls controls-row">
        <input type="text" placeholder="Your Name" class="span4" />
        <input type="text" placeholder="E-Mail Address" class="span4" />
    </div>
    {% endif %}
    <div class="controls controls-row">
        <textarea class="span8" placeholder="Your Comments"></textarea>
    </div>
    <div class="controls controls-row">
        <input type="submit" class="btn btn-primary" value="Submit" />
    </div>
    {% csrf_token %}
</form>

Elimdeki proje bittikten sonra gelen Edit:
Context instance olarak zaten request objesi gönderilmiş ve user objesi context’in içinde halihazırda mevcut. Dolayısıyla inclusion tag tanımlarken aşağıdaki gibi bir tanımlama yapmamıza gerek yok. Zaten takes_context dediğimizde context içeriği include edilen template e push ediliyor.
Aşağıdaki değişikliği yapabilirsiniz:
Eski:

@register.inclusion_tag('blog/post/blocks/comment/new.html', takes_context=True)
def show_comment_input(context):
    return {'user' : context['user']}

Yeni:

@register.inclusion_tag('blog/post/blocks/comment/new.html', takes_context=True)
def show_comment_input(context):
    pass

Kaynaklar:
http://stackoverflow.com/questions/2160261/access-request-in-django-custom-template-tags
http://stackoverflow.com/questions/3337419/django-user-is-authenticated-works-some-places-not-others

Share Button

About İbrahim Gündüz

1983 yılında İstanbul’da doğdu. İlkokul yıllarında cobol ve basic le olan tanışması, yazılıma olan ilgisini arttırdı 2005 yılında. Uludağ Üniversitesi Teknik Bilimler Meslek Yüksek Okulu Elektronik bölümünden mezun olan Gündüz, çeşitli alanlarda faaliyet gösteren kurumlarda yazılım geliştirici olarak görev almıştır. Mesleki ilgi alanları, ölçeklenebilir sistemler, uygulama entegrasyonları ve ödeme sistemleridir. Halen Markafoni back end geliştirici olarak çalışmaktadır.

Bir Cevap Yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir