<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>&#8235;ליאור שיאון - קיים משמע אני חושב. &#187; תכנות&#8236;</title>	<atom:link href="http://lior.sion.co.il/category/%d7%98%d7%9b%d7%a0%d7%99/%d7%aa%d7%9b%d7%a0%d7%95%d7%aa/feed/" rel="self" type="application/rss+xml" />
	<link>http://lior.sion.co.il</link>
	<description>&#8235;קוד, טכנולוגיה, מחשבות.&#8236;</description>	<lastBuildDate>Thu, 11 Aug 2011 07:33:22 +0000</lastBuildDate>
	<language>he</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>&#8235;פייראפ ישראל עלה לאויר &#8211; פרוייקט קהילתי&#8236;</title>		<link>http://lior.sion.co.il/2011/08/11/%d7%a4%d7%99%d7%99%d7%a8%d7%90%d7%a4-%d7%99%d7%a9%d7%a8%d7%90%d7%9c-%d7%a2%d7%9c%d7%94-%d7%9c%d7%90%d7%95%d7%99%d7%a8-%d7%a4%d7%a8%d7%95%d7%99%d7%99%d7%a7%d7%98-%d7%a7%d7%94%d7%99%d7%9c%d7%aa%d7%99/</link>
		<comments>http://lior.sion.co.il/2011/08/11/%d7%a4%d7%99%d7%99%d7%a8%d7%90%d7%a4-%d7%99%d7%a9%d7%a8%d7%90%d7%9c-%d7%a2%d7%9c%d7%94-%d7%9c%d7%90%d7%95%d7%99%d7%a8-%d7%a4%d7%a8%d7%95%d7%99%d7%99%d7%a7%d7%98-%d7%a7%d7%94%d7%99%d7%9c%d7%aa%d7%99/#comments</comments>
		<pubDate>Thu, 11 Aug 2011 07:33:22 +0000</pubDate>
		<dc:creator>&#8235;ליאור&#8236;</dc:creator>				<category><![CDATA[django]]></category>
		<category><![CDATA[אינטרנט]]></category>
		<category><![CDATA[טכני]]></category>
		<category><![CDATA[פייתון]]></category>
		<category><![CDATA[קוד פתוח]]></category>
		<category><![CDATA[תכנות]]></category>
		<category><![CDATA[junction]]></category>
		<category><![CDATA[pairup]]></category>
		<category><![CDATA[פייראפ]]></category>

		<guid isPermaLink="false">http://lior.sion.co.il/?p=585</guid>
		<description><![CDATA[&#8235;כשהייתי בjunction התפתח לו נוהג לפני כל פגישה לשאול אנשים אם הם מחפשים שותפים לסטארטפ, או מחפשים להצטרף כשותפים. המשפטים היו די ברורים: אני כך וכך, המיזם שלי עושה כך וכך, ואני חפש כך וכך. לא עבר זמן רב ונפתח אקסל משותף בגוגל שערך את כל הנתונים. הבעיה באקסל היתה שלא היתה דרך לנהל את התוכן, לראות [...]&#8236;]]></description>			<content:encoded><![CDATA[<div dir="rtl"><p>כשהייתי <a href="http://thejunction.co.il/" target="_blank">בjunction</a> התפתח לו נוהג לפני <a href="http://www.meetup.com/The-Junction/" target="_blank">כל פגישה</a> לשאול אנשים אם הם מחפשים שותפים לסטארטפ, או מחפשים להצטרף כשותפים. המשפטים היו די ברורים: אני כך וכך, המיזם שלי עושה כך וכך, ואני חפש כך וכך. לא עבר זמן רב ונפתח אקסל משותף בגוגל שערך את כל הנתונים.</p>
<p>הבעיה באקסל היתה שלא היתה דרך לנהל את התוכן, לראות ולהסיר פוסטים ישניםף לחפש בקלות וכו. בטיסה חזרה שלי מארה&quot;ב לפני שבועיים החלטתי לשנות את זה &#8211; ולפני שבוע העלתי לאויר את <a href="http://pairup.org.il/" target="_blank">pairup israel</a> - שמטרתו לעזור ליזמים ישראלים למצא שותפים &#8211; או סטארטפים להצטרף אליהם. כמובן שהאתר די מוגבל, כיאה לאתר שנכתב ב12 שעות טיסה (פחות שתי ארוחות וסרט) &#8211; אבל הפטנקציונליות הבסיסית נמצאת שם ואפשר לשפר בהמשך.</p>
<p>בנוסף העלתי את הפרוייקט כ<a href="https://github.com/liorsion/Pairup-Israel" target="_blank">קוד פתוח בגיטהב</a> - אם אתם מתכנתי פייטון ורוצים לתרום או לשפר את מוזמנים. את רובו כתבתי בצורה הכי דג'נגואית שיכולתי תוך שימוש בקלאסים בסיסים ככל האפשר &#8211; אני מקווה שיהיה אפשר ללמוד הרבה מהפרוייקט אם אתם מתכנתים מתחילים.</p>
<p>כולם מוזמנים..</p>
<div style="float:right;margin:0px 0px 0px 0px;" id="wp_facebook_og"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Flior.sion.co.il%2F2011%2F08%2F11%2F%25d7%25a4%25d7%2599%25d7%2599%25d7%25a8%25d7%2590%25d7%25a4-%25d7%2599%25d7%25a9%25d7%25a8%25d7%2590%25d7%259c-%25d7%25a2%25d7%259c%25d7%2594-%25d7%259c%25d7%2590%25d7%2595%25d7%2599%25d7%25a8-%25d7%25a4%25d7%25a8%25d7%2595%25d7%2599%25d7%2599%25d7%25a7%25d7%2598-%25d7%25a7%25d7%2594%25d7%2599%25d7%259c%25d7%25aa%25d7%2599%2F&amp;layout=standard&amp;show-faces=true&amp;width=450&amp;locale=he_IL&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px; height:auto;"></iframe></div></div>]]></content:encoded>			<wfw:commentRss>http://lior.sion.co.il/2011/08/11/%d7%a4%d7%99%d7%99%d7%a8%d7%90%d7%a4-%d7%99%d7%a9%d7%a8%d7%90%d7%9c-%d7%a2%d7%9c%d7%94-%d7%9c%d7%90%d7%95%d7%99%d7%a8-%d7%a4%d7%a8%d7%95%d7%99%d7%99%d7%a7%d7%98-%d7%a7%d7%94%d7%99%d7%9c%d7%aa%d7%99/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>&#8235;מתכנת מעל גיל 45? הסתבכת&#8236;</title>		<link>http://lior.sion.co.il/2011/06/18/%d7%9e%d7%aa%d7%9b%d7%a0%d7%aa-%d7%9e%d7%a2%d7%9c-%d7%92%d7%99%d7%9c-45-%d7%94%d7%a1%d7%aa%d7%91%d7%9b%d7%aa/</link>
		<comments>http://lior.sion.co.il/2011/06/18/%d7%9e%d7%aa%d7%9b%d7%a0%d7%aa-%d7%9e%d7%a2%d7%9c-%d7%92%d7%99%d7%9c-45-%d7%94%d7%a1%d7%aa%d7%91%d7%9b%d7%aa/#comments</comments>
		<pubDate>Sat, 18 Jun 2011 03:20:10 +0000</pubDate>
		<dc:creator>&#8235;ליאור&#8236;</dc:creator>				<category><![CDATA[מחשבות]]></category>
		<category><![CDATA[עולם וחדשות]]></category>
		<category><![CDATA[תכנות]]></category>
		<category><![CDATA[גילי נחום]]></category>
		<category><![CDATA[משה קפלן]]></category>
		<category><![CDATA[רברסים]]></category>
		<category><![CDATA[רוורסים]]></category>

		<guid isPermaLink="false">http://lior.sion.co.il/?p=572</guid>
		<description><![CDATA[&#8235;פודקסט טוב נוסף של רברסים (האמת, המחלקה הסגורה, אבל מאיזו סיבה לא ברורה החליטו לא להפריד בין השניים) התחיל דיון מענין על מתכנתים מבוגרים יחסית (גילי קבע את הגיל 45 כמספר החשוב, אבל זה פחות משנה), והוביל אותי לפוסט הזה של משה קפלן, ומשהו בו הטריד אותי מאוד. משה בחור חכם שכותב יפה. הוא אוהב [...]&#8236;]]></description>			<content:encoded><![CDATA[<div dir="rtl"><p><a href="http://www.reversim.com/2011/06/102-final-class-7.html#comments" target="_blank"><a href="http://lior.sion.co.il/wp-content/uploads/2011/06/old-man-thoughts.jpg"><img class="alignright size-full wp-image-573" style="margin: 20px; border: 1px solid black;" title="old-man-thoughts" src="http://lior.sion.co.il/wp-content/uploads/2011/06/old-man-thoughts.jpg" alt="" width="234" height="350" /></a>פודקסט טוב נוסף של רברסים</a> (האמת, המחלקה הסגורה, אבל מאיזו סיבה לא ברורה החליטו לא להפריד בין השניים) התחיל דיון מענין על מתכנתים מבוגרים יחסית (<a href="http://gilinachum.com/wp/" target="_blank">גילי</a> קבע את הגיל 45 כמספר החשוב, אבל זה פחות משנה), והוביל אותי ל<a href="http://blogs.microsoft.co.il/blogs/vprnd/archive/2011/05/26/837752.aspx?utm_source=feedburner&amp;utm_medium=feed&amp;utm_campaign=Feed%3A+vprndhandbook+%28%D7%94%D7%91%D7%9C%D7%95%D7%92+%D7%94%D7%A4%D7%AA%D7%95%D7%97+%D7%9C%D7%9E%D7%A0%D7%94%D7%9C+%D7%94%D7%A4%D7%99%D7%AA%D7%95%D7%97%29" target="_blank">פוסט הזה </a>של משה קפלן, ומשהו בו הטריד אותי מאוד.</p>
<p>משה בחור חכם שכותב יפה. הוא אוהב את שיטת הפוסטים הרשימתית (<a href="http://www.problogger.net/archives/2005/12/30/tens-tips-for-writing-a-blog-post/" target="_blank">כי ככה צריך לכתוב פוסטים טובים</a>), ואני חייב לציין שלרוב אני אוהב לקרא את הרשימות האלה, הן מדוייקות, מעניינות ומוסיפות לי ידע. אבל הפעם משהו לא הקליק לי נכון, ניסיתי להבין מה ולכן החלטתי לכתוב את הפוסט הזה.</p>
<p>הבעיה עם אנשי תוכנה מבוגרים לא פשוטה. היא קשורה, בין השאר, לעובדה שהתחום שלנו כולו הוא צעיר, משתנה מאוד, וחוקים כללים עדיין לא ברורים בו. האם נסיון של עשרות שנים רלוונטי תמיד בעולם של פרדיגמות משתנות? מהי החשיבות של עדכנות מיידית בטכנולוגיות חדשות, ומהי החשיבות (במיוחד בעולם הווב) של שימוש אישי בשירותים חדשים (האם תוכל להיות מתכנת טוב אם אתה לא משתמש בפייסבוק? אם לא ראית את טרנטייבל?) &#8211; ואולי החשוב ביותר: בעולם הסטארטאפים המשתנה הדגש על חברתיות, כיף בעבודה ושיטות ניהול חדשות הוא גדול מאוד &#8211; האם באמת התירוץ הקבוע של &quot;חוסר התאמה לאופי החברה&quot; הוא כל כך לא רלוונטי?</p>
<p>יש הרבה תשובות טובות לשאלות האלה, יש מספר דיונים שיכולים לצאת מהן. יש אנשים שתמיד נשארים מעודכנים, פשוט כי הם אוהבים את מה שהם עושים. יש אנשים שבודקים כל דבר חדש שיוצא, ויכולים לספר לך לא רק מה חדש שם, אלא מי עשה את זה בעבר, טוב יותר או רע יותר, מה ההבדלים ולמה זה עבד וההוא לא. כאן הנסיון של השנים מתחיל לעבוד חזק, ומצאתי שאנשים כאלה נתקלים פחות בבעיה של &quot;חוסר התאמה&quot;, אולי משום שהם יותר מתאימים גם ברוחם לאנשים צעירים? &#8211; מה שמגדיל את החשד שלי שחוסר ההתאמה הזו מוצדקת לעיתים ואינה קשורה ישירות לגיל &#8211; אלא לתרגיל.</p>
<p>הבעיה בפוסט של משה שהוא לא מסביר את האתגר בצורה נכונה אלא רק נותן את הפתרון, ומי שיעשה את מה שהוא אומר בצורה עיוורת לא יקבל תוצאות טובות מספיק. רן מזכיר את זה בפודקאסט בצורה יותר כללית: אם אתה אוהב מה שאתה עושה, קורא כל הזמן, נשאר מעודכן, תהיה בסדר. אני מסכים עם הגישה הזו. מישהו שואל שם (לא זיהיתי את הקול, אני חושב שזה גילי) אם זה לא מתיש עם הזמן &#8211; ועונים לו שלא. לזה אני לא מסכים: לפעמים זה מתיש. לפעמים אתה רוצה קצת לנוח ולתת חתיכת קוד טובה ולא לחשוב מעבר, אבל זה לא המקצוע שלנו. המקצוע שלנו דורש עדכון מתמיד. לפעמים זה מרגיש כמו רדיפה, אבל זה מה שאנחנו עושים. קוד פתוח משתנה מהר, תאהבו את זה או תשנאו את זה.</p>
<p>מה שחשוב זה להבין את העולם הזה, לקבל אותו ולרוץ איתו. זמן ונסיון בלבד לא הופכים אותך למתכנת טוב. אולי זו פרדיגמה שעבדה במקומות אחרים, אולי גם זה מעולם לא היה נכון, אבל אם אתם מתכנתים ורואים עצמכם עובדים במקצוע בעתיד &#8211; עשו לעצמכם טובה והפנימו את הדבר ה&quot;קטן&quot; הזה. אתם חייבים להתקרב לעולם התכנות כל יום מחדש כאילו הוא היום הראשון. לבדוק, להתעדכן, ללמוד. להשתתף.</p>
<div style="float:right;margin:0px 0px 0px 0px;" id="wp_facebook_og"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Flior.sion.co.il%2F2011%2F06%2F18%2F%25d7%259e%25d7%25aa%25d7%259b%25d7%25a0%25d7%25aa-%25d7%259e%25d7%25a2%25d7%259c-%25d7%2592%25d7%2599%25d7%259c-45-%25d7%2594%25d7%25a1%25d7%25aa%25d7%2591%25d7%259b%25d7%25aa%2F&amp;layout=standard&amp;show-faces=true&amp;width=450&amp;locale=he_IL&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px; height:auto;"></iframe></div></div>]]></content:encoded>			<wfw:commentRss>http://lior.sion.co.il/2011/06/18/%d7%9e%d7%aa%d7%9b%d7%a0%d7%aa-%d7%9e%d7%a2%d7%9c-%d7%92%d7%99%d7%9c-45-%d7%94%d7%a1%d7%aa%d7%91%d7%9b%d7%aa/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>&#8235;Django Unit Test על דאטהבייס חלופי&#8236;</title>		<link>http://lior.sion.co.il/2011/06/11/django-unit-test-%d7%a2%d7%9c-%d7%93%d7%90%d7%98%d7%94%d7%91%d7%99%d7%99%d7%a1-%d7%97%d7%9c%d7%95%d7%a4%d7%99/</link>
		<comments>http://lior.sion.co.il/2011/06/11/django-unit-test-%d7%a2%d7%9c-%d7%93%d7%90%d7%98%d7%94%d7%91%d7%99%d7%99%d7%a1-%d7%97%d7%9c%d7%95%d7%a4%d7%99/#comments</comments>
		<pubDate>Sat, 11 Jun 2011 14:12:37 +0000</pubDate>
		<dc:creator>&#8235;ליאור&#8236;</dc:creator>				<category><![CDATA[django]]></category>
		<category><![CDATA[טכני]]></category>
		<category><![CDATA[פייתון]]></category>
		<category><![CDATA[קוד פתוח]]></category>
		<category><![CDATA[תכנות]]></category>
		<category><![CDATA[postgres]]></category>
		<category><![CDATA[unit test]]></category>
		<category><![CDATA[בדיקות]]></category>

		<guid isPermaLink="false">http://lior.sion.co.il/?p=567</guid>
		<description><![CDATA[&#8235;הפוסט הזה הוא מעין פוסט למתקדמים &#8211; למרות שרציתי לכתוב פוסט למתחילים על בדיקות עצמיות ויוניט טסטס, לא מצאתי את הזמן לצערי, ואפילו את הפוסט הזה כבר תכננתי לכתוב לפני שלושה חודשים כמעט, ורק היום כשאני מחכה לסיום בדיקות של גירסה חדשה של האתר, וכן להעלאת קבצים באתר אחר, החלטתי להתיישב על זה. למרות שהפוסט [...]&#8236;]]></description>			<content:encoded><![CDATA[<div dir="rtl"><p>הפוסט הזה הוא מעין פוסט למתקדמים &#8211; למרות שרציתי לכתוב פוסט למתחילים על בדיקות עצמיות ויוניט טסטס, לא מצאתי את הזמן לצערי, ואפילו את הפוסט הזה כבר תכננתי לכתוב לפני שלושה חודשים כמעט, ורק היום כשאני מחכה לסיום בדיקות של גירסה חדשה של האתר, וכן להעלאת קבצים באתר אחר, החלטתי להתיישב על זה. למרות שהפוסט מדבר על שלוש שיטות אני כותב את הראשונה ומקווה לכתוב את השאר בעתיד הקרוב (שבוע שבועיים).</p>
<p>רציתי לתאר שלוש שיטות שונות שמתגברות על בעיות מאוד ספציפיות בדיקות unit test בdjango הקשורות לסביבות שאתם עובדים בהן. אלה לא בהכרח בעיות שכולם נתקלים בהן, ומתי שכן הפתרון הוא חד פעמי, ועדיין, חשוב לכתוב אותו ואולי לשמוע דעות של אחרים על הפתרון ועל אלטרנטיבות אחרות.</p>
<h2>בדיקות על POSTGRES</h2>
<p>Django מגיע עם דאטהבייס sqlite המיועד לפיתוח בלבד, עובד חזק בזכרון ולא תומך כל כך טוב בכמה משתמשים בו זמנית &#8211; אבל הוא קל ומהיר. הבעיה מתחילה שבעולם האמיתי אתם משתמשים במוצר אחר (אני משתמש כרגע בpostgres) ויש חוסר תאימות בחלק מהמוצרים או בביצועים. אני לא אכנס להחלטה האם כדאי לפתח על אותה סביבה של המוצר, עד כמה רחוק ללכת וכו. רק אציין שאצלי אכן עברתי מsqlite לpostgres בפיתוח, ואז מתקלתי בבעיה: בכל תחילת ריצה מנוע הבדיקות של django מבקש למחוק את בסיס הנתונים כדי להתחיל נקי.. אופס! לא רציתי את זה כי בסיס הנתונים מכיל מידע שאני אוהב לבדוק איתו בבדיקות הידניות.. אבל אני רוצה גם וגם!</p>
<p><strong>הפתרון</strong>: קובץ קונפיגורציה שונה (או נוסף) לבדיקות. ממילא היו לי שני קבצים (local, production) החלטתי להוסיף קובץ שלישי שכל מטרתו לקנפג בסיס נתונים חדש:</p>
<p>במקרה שלי מכל מיני סיבות החלטתי שהקובץ ירש מהקובץ המקומי (קובץ הproduction) מקבל כל מיני נתונים שלא תלויים בי ולא רציתי לשמור את התלות הזו), ואז פשוט להוסיף את השורות הבאות שמשנות את הנתונים שחשובים לי:</p>
<pre dir="ltr">try:
from settings import *
except ImportError:
pass

<code dir="ltr">EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'</code>

<code dir="ltr">DATABASES = {
'default': {
# Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'ENGINE': 'django.db.backends.sqlite3',
'NAME': project/dev.db',                      # Or path to database file if using sqlite3.
'USER': '',                      # Not used with sqlite3.
'PASSWORD': '',                  # Not used with sqlite3.
'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
'PORT': '',
},
}</code></pre>
<p dir="ltr"><code dir="ltr">&lt;p style="text-align: right;"&gt;&lt;code dir="ltr"&gt; </code><br />
בשילוב עם <a href="http://lior.sion.co.il/2011/03/16/%D7%93%D7%92%D7%A0%D7%92%D7%95-%D7%9C%D7%94%D7%A8%D7%99%D7%A5-%D7%91%D7%93%D7%99%D7%A7%D7%95%D7%AA-%D7%A8%D7%A7-%D7%A2%D7%9C-%D7%94%D7%97%D7%9C%D7%A7%D7%99%D7%9D-%D7%A9%D7%9C%D7%9A/">הרצה של הבדיקות רק על החלקים שלי</a>, פקודת הבדיקה תהיה:</p>
<pre dir="ltr">./manage.py test_watook --settings test-settings</pre>
<p style="text-align: right;">בעיה שנייה</p>
<p></code></p>
<div style="float:right;margin:0px 0px 0px 0px;" id="wp_facebook_og"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Flior.sion.co.il%2F2011%2F06%2F11%2Fdjango-unit-test-%25d7%25a2%25d7%259c-%25d7%2593%25d7%2590%25d7%2598%25d7%2594%25d7%2591%25d7%2599%25d7%2599%25d7%25a1-%25d7%2597%25d7%259c%25d7%2595%25d7%25a4%25d7%2599%2F&amp;layout=standard&amp;show-faces=true&amp;width=450&amp;locale=he_IL&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px; height:auto;"></iframe></div></div>]]></content:encoded>			<wfw:commentRss>http://lior.sion.co.il/2011/06/11/django-unit-test-%d7%a2%d7%9c-%d7%93%d7%90%d7%98%d7%94%d7%91%d7%99%d7%99%d7%a1-%d7%97%d7%9c%d7%95%d7%a4%d7%99/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>&#8235;קצרצר: לאתחל את סיסמת המנהל (admin) בדג&#039;נגו&#8236;</title>		<link>http://lior.sion.co.il/2011/03/29/%d7%a7%d7%a6%d7%a8%d7%a6%d7%a8-%d7%9c%d7%90%d7%aa%d7%97%d7%9c-%d7%90%d7%aa-%d7%a1%d7%99%d7%a1%d7%9e%d7%aa-%d7%94%d7%9e%d7%a0%d7%94%d7%9c-admin-%d7%91%d7%93%d7%92%d7%a0%d7%92%d7%95/</link>
		<comments>http://lior.sion.co.il/2011/03/29/%d7%a7%d7%a6%d7%a8%d7%a6%d7%a8-%d7%9c%d7%90%d7%aa%d7%97%d7%9c-%d7%90%d7%aa-%d7%a1%d7%99%d7%a1%d7%9e%d7%aa-%d7%94%d7%9e%d7%a0%d7%94%d7%9c-admin-%d7%91%d7%93%d7%92%d7%a0%d7%92%d7%95/#comments</comments>
		<pubDate>Tue, 29 Mar 2011 16:11:13 +0000</pubDate>
		<dc:creator>&#8235;ליאור&#8236;</dc:creator>				<category><![CDATA[django]]></category>
		<category><![CDATA[טיפים טכניים]]></category>
		<category><![CDATA[טכני]]></category>
		<category><![CDATA[פייתון]]></category>
		<category><![CDATA[קוד פתוח]]></category>
		<category><![CDATA[אדמין]]></category>
		<category><![CDATA[איתחול]]></category>
		<category><![CDATA[מנהל]]></category>
		<category><![CDATA[סיסמה]]></category>

		<guid isPermaLink="false">http://lior.sion.co.il/?p=546</guid>
		<description><![CDATA[&#8235;משהו שקורה לי כל כמה זמן &#8211; אני שוכח את הסיסמה לאדמין שלי. יש שיטה קלה יחסית להחליף אותה, וזה ע&#34;י כניסה לdatabase: הכנסו לshell החביב עליכם. לרוב אני משתמש בshell_plus של הdjango extensions שהוא shell רגיל (כמו django shell רק שהוא מעלה אוטומטית את כל המודולים שלכם): from django.contrib.auth.models import User us = User.objects.get(username="{{ [...]&#8236;]]></description>			<content:encoded><![CDATA[<div dir="rtl"><p>משהו שקורה לי כל כמה זמן &#8211; אני שוכח את הסיסמה לאדמין שלי. יש שיטה קלה יחסית להחליף אותה, וזה ע&quot;י כניסה לdatabase:</p>
<p>הכנסו לshell החביב עליכם. לרוב אני משתמש בshell_plus של ה<a href="https://github.com/django-extensions/django-extensions" target="_blank">django extensions</a> שהוא shell רגיל (כמו django shell רק שהוא מעלה אוטומטית את כל המודולים שלכם):</p>
<pre dir="ltr"><code>from django.contrib.auth.models import User

us = User.objects.get(username="{{ your username }}")

us.set_password('{{ your password}}')

us.save()
</code></pre>
<p>פשוט, לא?</p>
<div style="float:right;margin:0px 0px 0px 0px;" id="wp_facebook_og"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Flior.sion.co.il%2F2011%2F03%2F29%2F%25d7%25a7%25d7%25a6%25d7%25a8%25d7%25a6%25d7%25a8-%25d7%259c%25d7%2590%25d7%25aa%25d7%2597%25d7%259c-%25d7%2590%25d7%25aa-%25d7%25a1%25d7%2599%25d7%25a1%25d7%259e%25d7%25aa-%25d7%2594%25d7%259e%25d7%25a0%25d7%2594%25d7%259c-admin-%25d7%2591%25d7%2593%25d7%2592%25d7%25a0%25d7%2592%25d7%2595%2F&amp;layout=standard&amp;show-faces=true&amp;width=450&amp;locale=he_IL&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px; height:auto;"></iframe></div></div>]]></content:encoded>			<wfw:commentRss>http://lior.sion.co.il/2011/03/29/%d7%a7%d7%a6%d7%a8%d7%a6%d7%a8-%d7%9c%d7%90%d7%aa%d7%97%d7%9c-%d7%90%d7%aa-%d7%a1%d7%99%d7%a1%d7%9e%d7%aa-%d7%94%d7%9e%d7%a0%d7%94%d7%9c-admin-%d7%91%d7%93%d7%92%d7%a0%d7%92%d7%95/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>&#8235;חשיבות הכיסוי (coverage) בבדיקות התוכנה &#8211; ואיך עושים את זה בד&#039;נגו&#8236;</title>		<link>http://lior.sion.co.il/2011/03/19/%d7%97%d7%a9%d7%99%d7%91%d7%95%d7%aa-%d7%94%d7%9b%d7%99%d7%a1%d7%95%d7%99-coverage-%d7%91%d7%91%d7%93%d7%99%d7%a7%d7%95%d7%aa-%d7%94%d7%aa%d7%95%d7%9b%d7%a0%d7%94-%d7%95%d7%90%d7%99%d7%9a-%d7%a2/</link>
		<comments>http://lior.sion.co.il/2011/03/19/%d7%97%d7%a9%d7%99%d7%91%d7%95%d7%aa-%d7%94%d7%9b%d7%99%d7%a1%d7%95%d7%99-coverage-%d7%91%d7%91%d7%93%d7%99%d7%a7%d7%95%d7%aa-%d7%94%d7%aa%d7%95%d7%9b%d7%a0%d7%94-%d7%95%d7%90%d7%99%d7%9a-%d7%a2/#comments</comments>
		<pubDate>Sat, 19 Mar 2011 09:13:52 +0000</pubDate>
		<dc:creator>&#8235;ליאור&#8236;</dc:creator>				<category><![CDATA[django]]></category>
		<category><![CDATA[טיפים טכניים]]></category>
		<category><![CDATA[טכני]]></category>
		<category><![CDATA[פייתון]]></category>
		<category><![CDATA[קוד פתוח]]></category>
		<category><![CDATA[תכנות]]></category>
		<category><![CDATA[coverage]]></category>
		<category><![CDATA[unit test]]></category>
		<category><![CDATA[בדיקות]]></category>
		<category><![CDATA[כיסוי]]></category>

		<guid isPermaLink="false">http://lior.sion.co.il/?p=533</guid>
		<description><![CDATA[&#8235;בפוסט הקודם (על בדיקות תוכנה חלקיות בdjango) כתבתי על היכולת לבדוק רק מה שאתה כותב בתוך הפרוייקט. השלב הבא ההגיוני הוא להבין עד כמה הבדיקות האלה טובות. מכיוון שעדיין לא נתקלתי במישהו שחושב שבדיקות coverage חשובות כמו שאני חושב, אני רוצה לעצור כאן רגע ולדבר על הקונספט עצמו לרגע. מהן בדיקות כיסוי (coverage) פירוט והסבר [...]&#8236;]]></description>			<content:encoded><![CDATA[<div dir="rtl"><p>בפוסט הקודם (על <a href="http://lior.sion.co.il/2011/03/16/%D7%93%D7%92%D7%A0%D7%92%D7%95-%D7%9C%D7%94%D7%A8%D7%99%D7%A5-%D7%91%D7%93%D7%99%D7%A7%D7%95%D7%AA-%D7%A8%D7%A7-%D7%A2%D7%9C-%D7%94%D7%97%D7%9C%D7%A7%D7%99%D7%9D-%D7%A9%D7%9C%D7%9A/">בדיקות תוכנה חלקיות בdjango</a>) כתבתי על היכולת לבדוק רק מה שאתה כותב בתוך הפרוייקט. השלב הבא ההגיוני הוא להבין עד כמה הבדיקות האלה טובות.</p>
<p>מכיוון שעדיין לא נתקלתי במישהו שחושב שבדיקות coverage חשובות כמו שאני חושב, אני רוצה לעצור כאן רגע ולדבר על הקונספט עצמו לרגע.</p>
<h2>מהן בדיקות כיסוי (coverage)</h2>
<p>פירוט והסבר מלא אפשר למצא <a href="http://he.wikipedia.org/wiki/%D7%9E%D7%93%D7%93%D7%99_%D7%9B%D7%99%D7%A1%D7%95%D7%99_%D7%A7%D7%95%D7%93" target="_blank">בוויקיפדיה</a> (או כרגיל, בגרסה הטובה בהרבה <a href="http://en.wikipedia.org/wiki/Code_coverage" target="_blank">באנגלית</a>). הרעיון הוא פשוט: מריצים בדיקות אוטומטית או ידיניות, ובמקביל לגמרי, בלי קשר לבדיקות, בודקים <strong>מה</strong> בדיוק מורץ. אפשר לבדוק מדדים שונים (קוד, שורות, מסלולים ועוד) &#8211; אבל הרעיון דומה: בסופו של התהליך זוהי הדרך היחידה לדעת עד כמה הבדיקות שלכם מקיפות &#8211; ולכן להסיק עד כמה הן טובות. בצורה מפתיעה, אנשים רבים מבינים את חשיבות הבדיקות האוטומטיות (וגם זה שיפור לטובה) &#8211; אבל לא מבינים שללא הבנה של הכיסוי, ייתכן שהבדיקות שלכם לא שוות כלום.</p>
<p>חשוב לציין כמה נקודות קטנות בקשר לבדיקות האלה:</p>
<ul>
<li>קשה מאוד להגיע ל100% בדיקות, ומעט מאוד אנשים חושבים שזה היעד. יש תלות מסויימת בקוד הספציפי שלכם, אבל קטנה מאוד &#8211; אני ממליץ לנסות להגיע לפחות ל70% כיסוי, ולא לנסות להלחם יותר מדי על ה10% האחרונים.</li>
<li>בדיקות קוד צד לקוח בעתיות יותר ואני לא הולך להתיחס אליהן בפוסט הזה (במיוחד כי הדגש כרגע הוא על django)</li>
<li>התירוץ החוזר הוא ש&quot;הקוד שלנו שונה כי xyz, ולכן קשה בהרבה להגיע לכיסוי טוב&quot;. החליפו את xyz בדברים כמו &quot;הוא מערב הרבה מודולים שונים&quot;, &quot;אי אפשר להגיע לבדיקה של כל פינה&quot;, &quot;יש לנו הרבה יותר נקודות קצה&quot;, והחביב עלי: &quot;הקוד שלנו מאוד שונה כי הוא פועל על שילוב מחלקות שונות וקריאות מסובכות, תלויות חצוניות ודברים דומים&quot;. יש עוד הרבה כאלה. אל תקשיבו &#8211; עוד לא פגשתי קוד שבלתי אפשרי להגיע לאחוזים גבוהים של כיסוי &#8211; אם כי פגשתי קוד שהיה צריך לכתוב כמה mockups, נקודות קצה וירוטאליות ועוד משחקים שונים ומשונים.</li>
</ul>
<h2>בדיקות כיסוי בdjango</h2>
<p>בדיקות הכיסוי בdjango במוססות על <a href="http://nedbatchelder.com/code/coverage/" target="_blank">בדיקות כיסוי של נד בצ'לדר</a> (Ned Batchelder) שנמצאות גם <a href="http://pypi.python.org/pypi/coverage" target="_blank">כאן</a> או <a href="https://bitbucket.org/ned/coveragepy" target="_blank">כאן</a>. בחרו את הדרך הנוחה לכם להתקנה:</p>
<pre dir="ltr">pip install hg+https://bitbucket.org/ned/coveragepy</pre>
<p>או</p>
<pre dir="ltr">easy_install coverage</pre>
<p>וכדומה. בצורה דומה אפשר לחבר את החבילה לbuildout.</p>
<p>לאחר מכן התקינו את התוסף לdjango:</p>
<pre dir="ltr">https://bitbucket.org/kmike/django-coverage/src</pre>
<p>יש מספר תוספים אבל אני מחבב אותו. הופיעו שם כמה בעיות בחלק מהטמפלטים, אני מקווה שמתישהו אמצא זמן לשבת ולתקן &#8211; בנתיים, אפשר להשתמש בטמפלטים הרגילים.</p>
<p>לאחר שהתקנתם, הוספתם את django_coverage לsettingsINSTALLED_APPS, אתם כמעט מוכנים, ויכולים לבדוק את ההתקנה ע&quot;י הרצה של</p>
<p>python manage.py test_coverage</p>
<p>אני ממליץ ללכת שלב נוסף, כמו שהזכרתי בפוסט הקודם, וליצור בדיקות רק לקוד שלכם:</p>
<p>בתוך management-&gt;commands (<a href="http://lior.sion.co.il/2011/03/16/%D7%93%D7%92%D7%A0%D7%92%D7%95-%D7%9C%D7%94%D7%A8%D7%99%D7%A5-%D7%91%D7%93%D7%99%D7%A7%D7%95%D7%AA-%D7%A8%D7%A7-%D7%A2%D7%9C-%D7%94%D7%97%D7%9C%D7%A7%D7%99%D7%9D-%D7%A9%D7%9C%D7%9A/">הפוסט הקודם</a> מסביר את זה):</p>
<p><!-- p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Inconsolata} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Inconsolata; min-height: 14.0px} span.s1 {color: #3e00ff} span.s2 {text-decoration: underline} span.s3 {color: #00c100} span.s4 {color: #a00000} -->from django.core.management.base import AppCommand, BaseCommand</p>
<pre>
[python]
from django.core.management.base import AppCommand, BaseCommand
from django.core.management import call_command

from django.conf import settings

class Command(BaseCommand):

    def handle(self, *args, **options):
        test_app_path = ()
        for app in settings.MY_INSTALLED_APPS:
            test_app = app.split('.')
            if len(test_app) &gt; 1:
                test_app = (test_app[-1],)
            else:
                test_app = (app,)
            test_app_path += test_app
        call_command(&quot;test_coverage&quot;,*test_app_path, **options)

[/python]
</pre>
<p>הוסיפו בsettings שלכם את מיקום יצירת הhtml:</p>
<p>COVERAGE_REPORT_HTML_OUTPUT_DIR כדי לבחור את הספריה ליצירת תוצאות הHTML</p>
<div style="float:right;margin:0px 0px 0px 0px;" id="wp_facebook_og"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Flior.sion.co.il%2F2011%2F03%2F19%2F%25d7%2597%25d7%25a9%25d7%2599%25d7%2591%25d7%2595%25d7%25aa-%25d7%2594%25d7%259b%25d7%2599%25d7%25a1%25d7%2595%25d7%2599-coverage-%25d7%2591%25d7%2591%25d7%2593%25d7%2599%25d7%25a7%25d7%2595%25d7%25aa-%25d7%2594%25d7%25aa%25d7%2595%25d7%259b%25d7%25a0%25d7%2594-%25d7%2595%25d7%2590%25d7%2599%25d7%259a-%25d7%25a2%2F&amp;layout=standard&amp;show-faces=true&amp;width=450&amp;locale=he_IL&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px; height:auto;"></iframe></div></div>]]></content:encoded>			<wfw:commentRss>http://lior.sion.co.il/2011/03/19/%d7%97%d7%a9%d7%99%d7%91%d7%95%d7%aa-%d7%94%d7%9b%d7%99%d7%a1%d7%95%d7%99-coverage-%d7%91%d7%91%d7%93%d7%99%d7%a7%d7%95%d7%aa-%d7%94%d7%aa%d7%95%d7%9b%d7%a0%d7%94-%d7%95%d7%90%d7%99%d7%9a-%d7%a2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8235;דג&#039;נגו &#8211; להריץ בדיקות רק על החלקים שלך&#8236;</title>		<link>http://lior.sion.co.il/2011/03/16/%d7%93%d7%92%d7%a0%d7%92%d7%95-%d7%9c%d7%94%d7%a8%d7%99%d7%a5-%d7%91%d7%93%d7%99%d7%a7%d7%95%d7%aa-%d7%a8%d7%a7-%d7%a2%d7%9c-%d7%94%d7%97%d7%9c%d7%a7%d7%99%d7%9d-%d7%a9%d7%9c%d7%9a/</link>
		<comments>http://lior.sion.co.il/2011/03/16/%d7%93%d7%92%d7%a0%d7%92%d7%95-%d7%9c%d7%94%d7%a8%d7%99%d7%a5-%d7%91%d7%93%d7%99%d7%a7%d7%95%d7%aa-%d7%a8%d7%a7-%d7%a2%d7%9c-%d7%94%d7%97%d7%9c%d7%a7%d7%99%d7%9d-%d7%a9%d7%9c%d7%9a/#comments</comments>
		<pubDate>Wed, 16 Mar 2011 20:28:36 +0000</pubDate>
		<dc:creator>&#8235;ליאור&#8236;</dc:creator>				<category><![CDATA[django]]></category>
		<category><![CDATA[טיפים טכניים]]></category>
		<category><![CDATA[טכני]]></category>
		<category><![CDATA[פייתון]]></category>
		<category><![CDATA[קוד פתוח]]></category>
		<category><![CDATA[תכנות]]></category>
		<category><![CDATA[unit test]]></category>
		<category><![CDATA[בדיקות]]></category>
		<category><![CDATA[דג'נגו]]></category>
		<category><![CDATA[פקודות django]]></category>

		<guid isPermaLink="false">http://lior.sion.co.il/?p=526</guid>
		<description><![CDATA[&#8235;כחלק מפיתוח תוכנה רגילה בdjango אנשים מעודדים להשתמש (בתקווה גם לתרום) לקוד פתוח דרך ספריות מתוך pypi, github' bitbucket וכדומה. כל זה טוב ויפה, אבל מה קורה שאתה אוסף לך רשימה די ארוכה של אפליקציות, שרק חלק קטן מהן שלך, ואתה רוצה להריץ את הבדיקות שכתבת לעצמך (כי כולנו כותבים unit tests, נכון?)? הבעיה דג'נגו [...]&#8236;]]></description>			<content:encoded><![CDATA[<div dir="rtl"><p>כחלק מפיתוח תוכנה רגילה בdjango אנשים מעודדים להשתמש (בתקווה גם לתרום) לקוד פתוח דרך ספריות מתוך pypi, github' bitbucket וכדומה. כל זה טוב ויפה, אבל מה קורה שאתה אוסף לך רשימה די ארוכה של אפליקציות, שרק חלק קטן מהן שלך, ואתה רוצה להריץ את הבדיקות שכתבת לעצמך (כי כולנו כותבים unit tests, נכון?)?</p>
<h2>הבעיה</h2>
<p>דג'נגו תומך בפקודה manage.py test, שמריצה את כל הבדיקות מהאפליקציות המותקנות. אבל זה כולל בדיקות רבות שלא קשורות אליך, במקרה הטוב זה לוקח הרבה זמן, במקרה הרע חלק מהבדיקות לא עוברות משום שהן דורשות סביבה מיוחדת (במיוחד הבדיקות של django עצמה), ובמקרה הרע מאוד &#8211; הן פשוט לא עוברות.</p>
<p>הפקודה הנ&quot;ל גם מאפשרת להריץ חלק מהבדיקות &#8211; של אפליקציה אחת, או קבוצה אחת של אפליקציות, או אפילו בדיקה אחת. פרטים מלאים אפשר למצא ב<a href="http://docs.djangoproject.com/en/dev/topics/testing/#running-tests" target="_blank">מסמכים הרשמיים</a>.. אבל אי אפשר לבדוק רק את האפליקציות שלך, וזה מאוד מפריע לי</p>
<h2>הפתרון</h2>
<p>הפתרון קשור לדרך ולפרמטרים שהפקודה הנ&quot;ל כן תומכת בהם: אפשר להריץ בדיקות על מספר אפליקציות ע&quot;י קריאה לרשימת אפליקציות מופרדות ברווח:</p>
<p style="padding-left: 30px; text-align: left;">python manage.py test app1 app2 app3</p>
<p style="padding-left: 30px; text-align: right;">וכן מהיכולת להפריד את האפליקציות המותקנות לשתי רשימות, בלי לפגוע בעבודה היום יומית. לקחתי את הINSTALLED_APPS הרגיל שנמצא בsettings.py והפכתי אותו לשתי רשימות:</p>
<p><!-- p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Inconsolata} --></p>
<p dir="ltr">MY_INSTALLED_APPS = ( app1, app2 )</p>
<p><!-- p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Inconsolata} --></p>
<p dir="ltr">INSTALLED_APPS = MY_INSTALLED_APPS+( app3 )</p>
<p>בצורה הזו עדיין כל האפליקציות נמצאות בקובץ הsettings אחת ליד השניה, אין כפילות ואין בעיה לשמור על הסדר.</p>
<p>עכשיו רק צריך ליצור פקודה שרצה על MY_INSTALLED_APPS ומריצה על כל אחת מהן פקודת test. בשביל זה יצרתי <a href="http://docs.djangoproject.com/en/dev/howto/custom-management-commands/" target="_blank">פקודת שליטה</a>: בתוך הספרייה management-&gt;commands יצרתי קובץ test_apps, שבו הקוד:</p>
<p><!-- p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Inconsolata} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Inconsolata; min-height: 14.0px} span.s1 {color: #3e00ff} span.s2 {text-decoration: underline} span.s3 {color: #00c100} span.s4 {color: #a00000} --></p>
<pre dir="ltr">
[python]
from django.core.management.base import AppCommand, BaseCommand
from django.core.management import call_command

from django.conf import settings

class Command(BaseCommand):

    def handle(self, *args, **options):
        test_app_path = ()
        for app in settings.MY_INSTALLED_APPS:
            test_app = app.split('.')
            if len(test_app) &gt; 1:
                test_app = (test_app[-1],)
            else:
                test_app = (app,)
            test_app_path += test_app
        call_command(&quot;test&quot;,*test_app_path, **options)

[/python]
</pre>
<p>ועכשיו כשאני רוצה להריץ רק את הבדיקות שלי, אני פשוט מריץ python manage.py test_apps</p>
<p dir="ltr">&nbsp;</p>
<p style="padding-left: 30px; text-align: right;">&nbsp;</p>
<p>&nbsp;</p>
<div style="float:right;margin:0px 0px 0px 0px;" id="wp_facebook_og"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Flior.sion.co.il%2F2011%2F03%2F16%2F%25d7%2593%25d7%2592%25d7%25a0%25d7%2592%25d7%2595-%25d7%259c%25d7%2594%25d7%25a8%25d7%2599%25d7%25a5-%25d7%2591%25d7%2593%25d7%2599%25d7%25a7%25d7%2595%25d7%25aa-%25d7%25a8%25d7%25a7-%25d7%25a2%25d7%259c-%25d7%2594%25d7%2597%25d7%259c%25d7%25a7%25d7%2599%25d7%259d-%25d7%25a9%25d7%259c%25d7%259a%2F&amp;layout=standard&amp;show-faces=true&amp;width=450&amp;locale=he_IL&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px; height:auto;"></iframe></div></div>]]></content:encoded>			<wfw:commentRss>http://lior.sion.co.il/2011/03/16/%d7%93%d7%92%d7%a0%d7%92%d7%95-%d7%9c%d7%94%d7%a8%d7%99%d7%a5-%d7%91%d7%93%d7%99%d7%a7%d7%95%d7%aa-%d7%a8%d7%a7-%d7%a2%d7%9c-%d7%94%d7%97%d7%9c%d7%a7%d7%99%d7%9d-%d7%a9%d7%9c%d7%9a/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>&#8235;זיהוי משתמש לפי מייל בdjango&#8236;</title>		<link>http://lior.sion.co.il/2011/02/20/%d7%96%d7%99%d7%94%d7%95%d7%99-%d7%9e%d7%a9%d7%aa%d7%9e%d7%a9-%d7%9c%d7%a4%d7%99-%d7%9e%d7%99%d7%99%d7%9c-%d7%91django/</link>
		<comments>http://lior.sion.co.il/2011/02/20/%d7%96%d7%99%d7%94%d7%95%d7%99-%d7%9e%d7%a9%d7%aa%d7%9e%d7%a9-%d7%9c%d7%a4%d7%99-%d7%9e%d7%99%d7%99%d7%9c-%d7%91django/#comments</comments>
		<pubDate>Sun, 20 Feb 2011 12:19:36 +0000</pubDate>
		<dc:creator>&#8235;ליאור&#8236;</dc:creator>				<category><![CDATA[django]]></category>
		<category><![CDATA[טיפים טכניים]]></category>
		<category><![CDATA[טכני]]></category>
		<category><![CDATA[פייתון]]></category>
		<category><![CDATA[קוד פתוח]]></category>
		<category><![CDATA[תכנות]]></category>
		<category><![CDATA[django backend]]></category>
		<category><![CDATA[אימות משתמש]]></category>

		<guid isPermaLink="false">http://lior.sion.co.il/?p=517</guid>
		<description><![CDATA[&#8235;בdjango מודול ניהול המשתמשים די מתוחכם ומלא, אבל חסרה לו פונקציה בסיסית של אימות משתמש לפי מייל במקום לפי שם. מכיוון שזה שימוש שהולך ונהיה פופולרי באתרים ומכיוון שכמעט לא מצאתי דוגמאות קוד בעברית, החלטתי לכתוב בקצרה איך עושים את זה. ברמה התחתונה משתמשים מזוהים ע&#34;י שימוש בauthentication backend, שהם מודולים שמממשים קריאות מסויימות. מכיוון [...]&#8236;]]></description>			<content:encoded><![CDATA[<div dir="rtl"><p>בdjango מודול ניהול המשתמשים די מתוחכם ומלא, אבל חסרה לו פונקציה בסיסית של אימות משתמש לפי מייל במקום לפי שם. מכיוון שזה שימוש שהולך ונהיה פופולרי באתרים ומכיוון שכמעט לא מצאתי דוגמאות קוד בעברית, החלטתי לכתוב בקצרה איך עושים את זה.</p>
<p>ברמה התחתונה משתמשים מזוהים ע&quot;י שימוש בauthentication backend, שהם מודולים שמממשים קריאות מסויימות. מכיוון שמה שאנחנו עושים קרוב מאוד לשימוש הרגיל החלטתי לא לכתוב מההתחלה מודול שלם, אלא לרשת מהמודל הדיפולטיבי ופשוט לממש קריאה קצרה לזיהוי מייל במקרה שמזהים מייל בשם המשתמש.</p>
<p>שני דברים הנחו אותי בכתיבה:</p>
<p>1. אפשר לזהות מייל בכל מיני שיטות שונות ומתוחכמות. לא הכרחי ולא תמיד יעיל &#8211; החלטתי לחפש @ בשם המשתמש &#8211; דבר שאסור לפי החוקים במערכת שלי.</p>
<p>2. ליתר בטחון כמעט בכל מעבר (לא מצאתי @, לא מצאתי מייל וכו) &#8211; אני מעביר את הקריאה להמשך טיפול רגיל. במקרה הגרוע פגעתי בביצועים בעיקר בחיפוש אחד נוסף.</p>
<p>הנה הקוד:</p>
<pre style="text-align: left;" dir="ltr"><!-- p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Inconsolata} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Inconsolata; min-height: 14.0px} span.s1 {color: #a10066} span.s2 {color: #5700ff} -->from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User

class EmailUserBackend(ModelBackend):

    def authenticate(self, username=None, password=None):

        if '@' in username:

            try:

                user = User.objects.get(email=username)

                if user.check_password(password):

                    return user

            except User.DoesNotExist:

                pass

        return super(EmailUserBackend,self).authenticate(username, password)</pre>
<p style="text-align: right;">בנוסף, צריך להחליף את הקוד הנוכחי בsettings.py:</p>
<pre style="text-align: left;" dir="ltr"><!-- p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Inconsolata} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Inconsolata; color: #5700ff} p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px Inconsolata; color: #319573} span.s1 {color: #000000} -->AUTHENTICATION_BACKENDS = (

'gifts.giftuser.backend.EmailUserBackend',

#'django.contrib.auth.backends.ModelBackend',

)</pre>
<p>בהערה: הקוד הקודם.</p>
<div style="float:right;margin:0px 0px 0px 0px;" id="wp_facebook_og"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Flior.sion.co.il%2F2011%2F02%2F20%2F%25d7%2596%25d7%2599%25d7%2594%25d7%2595%25d7%2599-%25d7%259e%25d7%25a9%25d7%25aa%25d7%259e%25d7%25a9-%25d7%259c%25d7%25a4%25d7%2599-%25d7%259e%25d7%2599%25d7%2599%25d7%259c-%25d7%2591django%2F&amp;layout=standard&amp;show-faces=true&amp;width=450&amp;locale=he_IL&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px; height:auto;"></iframe></div></div>]]></content:encoded>			<wfw:commentRss>http://lior.sion.co.il/2011/02/20/%d7%96%d7%99%d7%94%d7%95%d7%99-%d7%9e%d7%a9%d7%aa%d7%9e%d7%a9-%d7%9c%d7%a4%d7%99-%d7%9e%d7%99%d7%99%d7%9c-%d7%91django/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>&#8235;תיקון אבטחה בdjango משנה קריאות ajax (אין תאימות אחורה)&#8236;</title>		<link>http://lior.sion.co.il/2011/02/16/%d7%aa%d7%99%d7%a7%d7%95%d7%9f-%d7%90%d7%91%d7%98%d7%97%d7%94-%d7%91django-%d7%9e%d7%a9%d7%a0%d7%94-%d7%a7%d7%a8%d7%99%d7%90%d7%95%d7%aa-ajax-%d7%90%d7%99%d7%9f-%d7%aa%d7%90%d7%99%d7%9e%d7%95%d7%aa/</link>
		<comments>http://lior.sion.co.il/2011/02/16/%d7%aa%d7%99%d7%a7%d7%95%d7%9f-%d7%90%d7%91%d7%98%d7%97%d7%94-%d7%91django-%d7%9e%d7%a9%d7%a0%d7%94-%d7%a7%d7%a8%d7%99%d7%90%d7%95%d7%aa-ajax-%d7%90%d7%99%d7%9f-%d7%aa%d7%90%d7%99%d7%9e%d7%95%d7%aa/#comments</comments>
		<pubDate>Wed, 16 Feb 2011 07:23:14 +0000</pubDate>
		<dc:creator>&#8235;ליאור&#8236;</dc:creator>				<category><![CDATA[django]]></category>
		<category><![CDATA[טכני]]></category>
		<category><![CDATA[פייתון]]></category>
		<category><![CDATA[קוד פתוח]]></category>
		<category><![CDATA[תכנות]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[אבטחה]]></category>

		<guid isPermaLink="false">http://lior.sion.co.il/?p=509</guid>
		<description><![CDATA[&#8235;אם אתם משתמשים בdjango עדכני ולפתע מקבלים שגיאת 403 לקריאות הajax שלכם ולא מבינים למה, כדאי שתקראו את זה. ב8 בפברואר שוחרר תיקון אבטחה בdjango שכלל גרסאות 1.1, 1.2 וגרסת הקוד האחרונה. הסיפור הוא די פשוט, אבל כדי להבין אותו כדאי לדעת כמה פרטים כללים על CSRF, למה משתמשים בזה ואיך. אם אתם יודעים אתם [...]&#8236;]]></description>			<content:encoded><![CDATA[<div dir="rtl"><p>אם אתם משתמשים בdjango עדכני ולפתע מקבלים שגיאת 403 לקריאות הajax שלכם ולא מבינים למה, כדאי שתקראו את זה.</p>
<p>ב8 בפברואר שוחרר <a href="http://www.djangoproject.com/weblog/2011/feb/08/security/" target="_blank">תיקון אבטחה</a> בdjango שכלל גרסאות 1.1, 1.2 וגרסת הקוד האחרונה. הסיפור הוא די פשוט, אבל כדי להבין אותו כדאי לדעת כמה פרטים כללים על CSRF, למה משתמשים בזה ואיך. אם אתם יודעים אתם יכולים לקפוץ על הפסקאות הבאות <a href="#solution">הישר לפתרון.</a></p>
<h2>מה זה CSRF</h2>
<p><a href="http://en.wikipedia.org/wiki/Cross-site_request_forgery" target="_blank">csrf</a> הם ראשי התיבות ל<strong>Cross-site request forgery, </strong>פירצת אבטחה המאפשרת שליחת פקודות לאתר בשמו של משתמש שהאתר מכיר ובוטח. בניגוד לxss המפורסמת קצת יותר, שבה מנצלים את האימון שהמשתמש נותן באתר. הרעיון בבסיסו פשוט מאוד: אם התוקף יודע שמשתמש מסויים מחובר לאתר, הוא שותל קוד באתר או באתר אחר, המפנה לפעולה מסויימת ושולח אותו במספר דרכים זדוניות למשתמש, אשר ביודעין או לא מפעיל את הקוד הזה. מכיוון שהמשתמש מחובר, האתר בוטח בו ובזהות שלו ומפעיל את הפקודה.</p>
<p>דוגמא פשוטה מתוך וויקיפידיה היא שתילת קוד בתוך כתובת של תמונה. הדפדפן של הקורבן ניגש להביא את התמונה, מזדהה כקורבן ומפעיל פעולה שאינה קשורה כלל לתמונה:</p>
<pre dir="ltr">&lt;img src="http://bank.example.com/withdraw?account=bob&amp;amount=1000000&amp;for=mallory"&gt;</pre>
<p>השיטה הפופלרית ביותר להתמודדות (זו שdjango משתמשת בה, וכן wordpress וruby) היא הוספת קוד סודי לפני קריאות אפשריות לשרת. אם הקוד לא שם אז השרת מתיחס לקריאה כפריצת אבטחה ומחזיר קוד 403.</p>
<p>עד כה, ההגנה הזו לא חלה על קריאות ajax בdjango, משום שיחסית קל לזהות אותן והמערכת הסתמכה על ההגנה האינרנטית של הדפדפן מפני התקפות כאלה, אולם מתברר שהשילוב הזה (הסתמכות על הדפדן שיזהה את הבקשה כajax וכן מנגנון הגנה של דפדפן) אינו הגיוני וכשל.<br />
<a name="solution"></a></p>
<h2>מהי ההתקפה האפשרית החדשה</h2>
<p>צוות של גוגל מצא אפשרות ליצור, בעזרת קומבינציה של תוספים לדפדפן ומספר redirects קריאה שנראית כמו ajax אבל למעשה אינה כזו, ובכך לגרום לצד הדפדפן לא להגן על המשתמש ולצד השרת לחשוב שכן &#8211; ובכך ליצור את הפירצה. הפתרון: הגנה בצד השרת גם על קריאות ajax, ולכן הפגיעה אחורה בקוד שלכם.<br />
למרבית ההפתעה (וחוסר הסדר), המסמכים הרשמיים נותנים שני פתרונות אפשריים אם אתם משתמשים בjquery. אחד נמצא ב<a href="http://www.djangoproject.com/weblog/2011/feb/08/security/" target="_blank">הודעה על השיחרור</a>, והשני ב<a href="http://docs.djangoproject.com/en/dev/releases/1.3/" target="_blank">מסמכים של הגירסה החדשה</a>. ישנם גם מספר דיונים על הדרך הטובה והיעילה ביותר לעשות את זה, אז שווה להמשיך לעקוב &#8211; אבל כרגע קודם כל לפתור את הבעיה.</p>
<p>אני אציג כאן רק את הפתרון הרשמי יותר, משום שהוא כללי ותומך בעוגיות, ואילו הפתרון השני מסתמך על נוכחות של form בקוד שלכם, מה שלא תמיד נכון.</p>
<pre style="text-align: left;" dir="ltr">$.ajaxSetup({
    beforeSend: function(xhr, settings) {
        function getCookie(name) {
            var cookieValue = null;
            if (document.cookie &amp;&amp; document.cookie != '') {
                var cookies = document.cookie.split(';');
                for (var i = 0; i &lt; cookies.length; i++) {
                    var cookie = jQuery.trim(cookies[i]);
                    // Does this cookie string begin with the name we want?
                    if (cookie.substring(0, name.length + 1) == (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }
        if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
            // Only send the token to relative URLs i.e. locally.
            xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
        }
    }
});</pre>
<p>תיאור הפתרון:</p>
<p>בעזרת jquery אנחנו תופסים כל בקשת ajax, ובודקים אם יש לנו עוגיה המכילה את המילה csrftoken, ומוסיפים אותה לבקשה.</p>
<div style="float:right;margin:0px 0px 0px 0px;" id="wp_facebook_og"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Flior.sion.co.il%2F2011%2F02%2F16%2F%25d7%25aa%25d7%2599%25d7%25a7%25d7%2595%25d7%259f-%25d7%2590%25d7%2591%25d7%2598%25d7%2597%25d7%2594-%25d7%2591django-%25d7%259e%25d7%25a9%25d7%25a0%25d7%2594-%25d7%25a7%25d7%25a8%25d7%2599%25d7%2590%25d7%2595%25d7%25aa-ajax-%25d7%2590%25d7%2599%25d7%259f-%25d7%25aa%25d7%2590%25d7%2599%25d7%259e%25d7%2595%25d7%25aa%2F&amp;layout=standard&amp;show-faces=true&amp;width=450&amp;locale=he_IL&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px; height:auto;"></iframe></div></div>]]></content:encoded>			<wfw:commentRss>http://lior.sion.co.il/2011/02/16/%d7%aa%d7%99%d7%a7%d7%95%d7%9f-%d7%90%d7%91%d7%98%d7%97%d7%94-%d7%91django-%d7%9e%d7%a9%d7%a0%d7%94-%d7%a7%d7%a8%d7%99%d7%90%d7%95%d7%aa-ajax-%d7%90%d7%99%d7%9f-%d7%aa%d7%90%d7%99%d7%9e%d7%95%d7%aa/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>&#8235;Django&#039;s get_model וסדר טעינת מודולים&#8236;</title>		<link>http://lior.sion.co.il/2011/02/01/djangos-get_model-%d7%95%d7%a1%d7%93%d7%a8-%d7%98%d7%a2%d7%99%d7%a0%d7%aa-%d7%9e%d7%95%d7%93%d7%95%d7%9c%d7%99%d7%9d/</link>
		<comments>http://lior.sion.co.il/2011/02/01/djangos-get_model-%d7%95%d7%a1%d7%93%d7%a8-%d7%98%d7%a2%d7%99%d7%a0%d7%aa-%d7%9e%d7%95%d7%93%d7%95%d7%9c%d7%99%d7%9d/#comments</comments>
		<pubDate>Tue, 01 Feb 2011 15:45:23 +0000</pubDate>
		<dc:creator>&#8235;ליאור&#8236;</dc:creator>				<category><![CDATA[django]]></category>
		<category><![CDATA[טיפים טכניים]]></category>
		<category><![CDATA[טכני]]></category>
		<category><![CDATA[פייתון]]></category>
		<category><![CDATA[קוד פתוח]]></category>
		<category><![CDATA[תכנות]]></category>
		<category><![CDATA[get_model]]></category>
		<category><![CDATA[social-auth]]></category>
		<category><![CDATA[טוויטר]]></category>
		<category><![CDATA[פייסבוק]]></category>

		<guid isPermaLink="false">http://lior.sion.co.il/?p=505</guid>
		<description><![CDATA[&#8235;היום היה יום עמוס במיוחד. הוא התחיל עם באג קטן שמצאתי בDjango, המשיך בכמה תיקונים בשתי חבילות חדשות שהתחלתי להשתמש (django-registration ו-django-social-auth) והמשיך הלאה משם. את התיקון בdjango לקח לי קצת זמן למצא פשוט מהסיבה שלא האמנתי שיש ממש באג בבסיס, אבל התיקון בsocial-auth היה מענין יותר. social-auth הוא תוסף המאפשר הרשמה של משתמשים מרשתות [...]&#8236;]]></description>			<content:encoded><![CDATA[<div dir="rtl"><p>היום היה יום עמוס במיוחד. הוא התחיל עם באג קטן שמצאתי בDjango, המשיך בכמה תיקונים בשתי חבילות חדשות שהתחלתי להשתמש (django-registration ו-django-social-auth) והמשיך הלאה משם. את התיקון בdjango לקח לי קצת זמן למצא פשוט מהסיבה שלא האמנתי שיש ממש באג בבסיס, אבל התיקון בsocial-auth היה מענין יותר.</p>
<p><a href="https://github.com/omab/django-social-auth/" target="_blank">social-auth </a> הוא תוסף המאפשר הרשמה של משתמשים מרשתות חברתיות לאפליקלציה שלך. אני משתמש <a href="http://developers.facebook.com/docs/authentication/" target="_blank">בפייסבוק</a>, <a href="http://dev.twitter.com/pages/oauth_faq" target="_blank">טוויטר</a> ואולי <a href="http://code.google.com/apis/accounts/docs/OAuth.html" target="_blank">גוגל</a> בהמשך, אבל התוסף עצמו תומך גם <a href="http://openid.yahoo.com/" target="_blank">ביאהו</a>, אורקוט ו<a href="http://code.google.com/apis/accounts/docs/OpenID.html" target="_blank">open id של גוגל</a> &#8211; לא רע בכלל.</p>
<p>ההסתבכות הגיעה כשהתחלתי להשתמש במודול משתמש משלי. אני שולף כמה נתונים מפייסבוק בנוסף לדברים הבסיסיים ביותר, ומכניס אותם לפרטי המשתמש &#8211; וכדי לעשות את זה אני משתמש בשני כלים שהתוסף מאפשר לי: <a href="http://docs.djangoproject.com/en/dev/topics/signals/" target="_blank">סיגנלים</a> ומודל משתמש מיוחד של דגנו.</p>
<p>סיגנלים הם כלי פשוט אבל חזק של הוקים וטריגרים במערכת. יש כמה שמגיעים עם המערכת (לפני ואחרי שמירת מודל לדוגמא) ויש אפשרות לבנות גם כמה סיגנלים משלך (כמו שהתוסף עשה). מהצד השני אתה בוחר לאיזה סוג של סיגנל אתה רוצה להקשיב, ופועל לפיו.</p>
<p>כדי להשתמש במודל כללי של משתמש, כמו שאני רציתי, התוסף השתמש בפונקציה נהדרת שנקראת get_model. זוהי פונקציה שמאפשרת קבלה של מודל,  ואז חקירה ושימוש שלו ללא ידיעה מראש מהו שם המודל. האפשרויות לשימוש בכלי כזה כמעט בלתי מוגבלות, במיוחד בשימוש בכלים חיצוניים ומודולים כלליים.</p>
<p>הבעיה היתה שמכיוון ששני השימושים הנ&quot;ל (הסיגנל והמודל המקומי) התיחסו למודל שלי של המשתמש, אפשרתי את שניהם באותו הקובץ, <strong>לפני </strong>ההגדרה של מודל המשתמש שלי. כל אחד מהנ&quot;ל יכל לעבוד, אבל ביחד &#8211; השימוש בסיגנל הכניס את המודל לזכרון, וברגע שהוא נכנס לזכרון הוא קרא לget_model כדי להעלות את המשתמש שלי &#8211; אבל זה עדיין לא היה נגיש בשלב הזה. התוצאה: התרסקות.</p>
<p>הפתרון &#8211; הוצאה של כל החבילה הזו למודול נפרד או הורדה לאותו מודול אבל מתחת להגדרה המקומית שלי. שניהם פתרונות לא אידיאליים מבחינת נכונות וסדר קוד, אבל זה מה יש.</p>
<div style="float:right;margin:0px 0px 0px 0px;" id="wp_facebook_og"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Flior.sion.co.il%2F2011%2F02%2F01%2Fdjangos-get_model-%25d7%2595%25d7%25a1%25d7%2593%25d7%25a8-%25d7%2598%25d7%25a2%25d7%2599%25d7%25a0%25d7%25aa-%25d7%259e%25d7%2595%25d7%2593%25d7%2595%25d7%259c%25d7%2599%25d7%259d%2F&amp;layout=standard&amp;show-faces=true&amp;width=450&amp;locale=he_IL&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px; height:auto;"></iframe></div></div>]]></content:encoded>			<wfw:commentRss>http://lior.sion.co.il/2011/02/01/djangos-get_model-%d7%95%d7%a1%d7%93%d7%a8-%d7%98%d7%a2%d7%99%d7%a0%d7%aa-%d7%9e%d7%95%d7%93%d7%95%d7%9c%d7%99%d7%9d/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8235;לקחי טכנולוגיה &#8211; 30.12.10 &#8211; buildout&#8236;</title>		<link>http://lior.sion.co.il/2011/01/02/%d7%9c%d7%a7%d7%97%d7%99-%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94-30-12-10-buildout/</link>
		<comments>http://lior.sion.co.il/2011/01/02/%d7%9c%d7%a7%d7%97%d7%99-%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94-30-12-10-buildout/#comments</comments>
		<pubDate>Sun, 02 Jan 2011 08:04:40 +0000</pubDate>
		<dc:creator>&#8235;ליאור&#8236;</dc:creator>				<category><![CDATA[טיפים טכניים]]></category>
		<category><![CDATA[טכני]]></category>
		<category><![CDATA[פייתון]]></category>
		<category><![CDATA[תכנות]]></category>
		<category><![CDATA[buildout]]></category>
		<category><![CDATA[קבךןפדק]]></category>

		<guid isPermaLink="false">http://lior.sion.co.il/?p=479</guid>
		<description><![CDATA[&#8235;כשבונים buildout לפייטון, במיוחד בסביבת eclipse, משתנה הextra-path יגרום לסקריפט להכניס נתונים לbin/django שלכם הכוללים את הpath לחבילות המותקנות. אם יש לכם מודל ספציפי שאתם רוצים להשתמש בו ישירות, אתם חייבים להכניס את השורה הזו. השוואה מצויינת של ביצועי ווב סרברז לפייטון שלא רק נכנסת לפרטי הבדיקות, בודקת הרבה סרסבים אלא גם מסבירה את ההבדלים, [...]&#8236;]]></description>			<content:encoded><![CDATA[<div dir="rtl"><ul>
<li>כשבונים buildout לפייטון, במיוחד בסביבת eclipse, משתנה הextra-path יגרום לסקריפט להכניס נתונים לbin/django שלכם הכוללים את הpath לחבילות המותקנות. אם יש לכם מודל ספציפי שאתם רוצים להשתמש בו ישירות, אתם חייבים להכניס את השורה הזו.</li>
<li>השוואה מצויינת של <a href="http://nichol.as/benchmark-of-python-web-servers" target="_blank">ביצועי ווב סרברז לפייטון</a> שלא רק נכנסת לפרטי הבדיקות, בודקת הרבה סרסבים אלא גם מסבירה את ההבדלים, ממה הם נובעים וכו. לכל האנשים שמדברים ביצועים אבל לא תמיד סגורים למה thread pool שונה מthread per process, הנה.</li>
</ul>
<div style="float:right;margin:0px 0px 0px 0px;" id="wp_facebook_og"><iframe src="http://www.facebook.com/plugins/like.php?href=http%3A%2F%2Flior.sion.co.il%2F2011%2F01%2F02%2F%25d7%259c%25d7%25a7%25d7%2597%25d7%2599-%25d7%2598%25d7%259b%25d7%25a0%25d7%2595%25d7%259c%25d7%2595%25d7%2592%25d7%2599%25d7%2594-30-12-10-buildout%2F&amp;layout=standard&amp;show-faces=true&amp;width=450&amp;locale=he_IL&amp;action=like&amp;font=arial&amp;colorscheme=light" scrolling="no" frameborder="0" allowTransparency="true" style="border:none; overflow:hidden; width:450px; height:auto;"></iframe></div></div>]]></content:encoded>			<wfw:commentRss>http://lior.sion.co.il/2011/01/02/%d7%9c%d7%a7%d7%97%d7%99-%d7%98%d7%9b%d7%a0%d7%95%d7%9c%d7%95%d7%92%d7%99%d7%94-30-12-10-buildout/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

