æè¿ã
ãã³ã¬ãŒãã³ã¬ã¹ãã©ã³ã®äºçŽãµãŒãã¹ãéå§ããŸããã ãã®äžã«ã¯ãå€ããå°ãªããå
žåçãªdjangoãµã€ãããããŸãã ãããã©ã®ããã«æ©èœãããã説æããŸãïŒåçä»ãïŒã ãã®èšäºã¯éåžžã«å·§åŠãªãã®ã§ã¯ãããŸãããã誰ããããã€ãã®ããªãã¯ãã¢ã€ãã¢ãèŠã€ããŠãäœããã®åœ¢ã§èªåã®äººçãç°¡çŽ åããŠãããããšãé¡ã£ãŠããŸãã
æšæºããŒã«ããã¯ã¹ã¯ãPostgreSQLãDjango 1.4ïŒ+ GeoDjangoïŒãSentryãCeleryïŒ+ redisïŒãFabricã§ãã
ã¹ã¿ãŒãããŒãž

ã¹ã¿ãŒãããŒãžã«ç°åžžãªãã®ã¯ãããŸããïŒç»é²ãã©ãŒã ã ç§ããã§ã«
æžããããã«ããã¥ãŒãã©ãŒã ã¯èªäœã§ããããããããã¥ãŒããã©ãŒã ã䜿çšããŠããªãããšã«æ°ä»ããåŸããžã£ã³ãŽç»é²ã¯inããã«åãåããŸãããã¢ãã«ãèªåŒããããšããŠãããžã§ã¯ãã®ãã°ãã©ãã«ãŒãç¡å¹ã«ãªããŸãã:)
ç»é²ãããšãæšæ¶ç¶ãéä¿¡ãããhtmlãšããŠäœæãããŸãã html-letterãéä¿¡ããã«ã¯ã
templated-emailsã䜿çšããŸãããã³ãã¬ãŒãã«ã¯ããã¹ãŠã®æåãä¿åãããemailsãã©ã«ããŒããããŸãã åã¬ã¿ãŒã¯ãemail.htmlïŒã¬ã¿ãŒã®htmlããŒãžã§ã³ïŒãemail.txtïŒã¬ã¿ãŒã®ããã¹ãããŒãžã§ã³ïŒãããã³short.txtïŒä»¶åïŒã®3ã€ã®ãã¡ã€ã«ãå«ãç¬èªã®ãã©ã«ããŒã«ãããŸãã

æçŽã¯æ¬¡ã®ããã«éãããŸãã
send_templated_email([user], 'emails/activation', context=context)
åä¿¡è
ã®ãªã¹ãã«ãŠãŒã¶ãŒãŸãã¯é»åã¡ãŒã«ã¢ãã¬ã¹ãéä¿¡ã§ããŸãã ãã³ã»ã³ã¹ã§ãããã·ã³ãã«ã§äŸ¿å©ãªãç§ãã¡ã¯ããªãé·ãéãããŸããŸãªãããžã§ã¯ãã§ãã®ã¢ãããŒãã䜿çšããŠããŸãã
html-letterã«ã¯ãã1ã€ã®åé¡ããããŸã-éçºäžã«ããããã©ã®ããã«èŠãã°èªåã«çµ¶ããéä¿¡ãããã¯ããŸãæç¢ºã§ã¯ãããŸããã ããŒã«ã«ã§ç¢ºèªããã«ã¯ã
django-eml-email-backend ïŒéä¿¡ãã代ããã«emlãã¡ã€ã«ã«æåãä¿åããé»åã¡ãŒã«ããã¯ãšã³ããåãããã ã¢ããªã±ãŒã·ã§ã³ïŒã䜿çšããŸãã ã»ãšãã©ã®ã¡ãŒã«ã¯ã©ã€ã¢ã³ãã¯åé¡ãªãemlãã¡ã€ã«ãéããŸãïŒã¹ããŒã¹ã«ãã£ãŠããããã¢ããã®ãã¬ãã¥ãŒããããŸãïŒã
ããããŸãããã¶ã¬ã®ã¹
ã¢ã«ãŠã³ããç»é²ããŠèšå®ãããšããŠãŒã¶ãŒã¯ã¡ã€ã³ããŒãžã«ç§»åããŸãã

ãã®äžã§ãæ€çŽ¢ãã©ãŒã ã«æ³šæãæãããšãã§ããŸãã

èŠçŽ ã¯ããšããšæ¬¡ã®ããã«ã¬ã€ã¢ãŠããããŠããŸããã
<div class="b-filter_selector time"> <select name="persons" data-behavior="Chosen"> <option value="1">1 </option> <option value="2" selected="selected>2 </option> <option value="3">3 </option> </select> </div>
é£äžã¯BEMã«åºå·ããããšããŸãããå
¥åã¯ãã°ãã°divã«ã©ããããããã°ãã°cssã¯ã©ã¹ãããŒã¿å±æ§ãªã©ã屿§ä»ãããå¿
èŠããããŸãã
Pythonã³ãŒãã§htmlãçž«ãã®ã¯æªãå³ã§ããhtmlã¯ãã³ãã¬ãŒãã«ããã¹ãã§ãã jungå
ã®ãã³ãã¬ãŒãå
ã®ãã©ãŒã èŠçŽ ã®ã¬ã³ããªã³ã°ã«åœ±é¿ãäžããéåžžã®çµã¿èŸŒã¿ããŒã«ã¯ãããŸããïŒããã§ã¯ããã£ãŒã«ãã«ããŒã¿ã®æ¯ãèãã远å ããå¿
èŠããããŸãïŒã ãã®ãããªããšãããã¬ã€ã¢ãŠãããã蟌ããšãã«django-widget-
tweaks ïŒ
bitbucket ã
github ïŒãéåžžã«ç©æ¥µçã«äœ¿çšããŠããããããã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãã蟌ã¿ããã»ã¹ãç°¡çŽ åããŠããŒãã«ã§ããŸãã
<div class="b-filter_selector time"> {% render_field search_form.persons data-behavior='Chosen' %} </div>
ãã£ãŒã«ãã«äœããã®çš®é¡ã®æšæºãã€ã³ãã£ã³ã°ãå¿
èŠãªå Žåãhtmlã¹ãããããäœæãã{ïŒ
includeïŒ
}ïŒæ¬¡ã®ãããªãã®ïŒãä»ããŠæ¥ç¶ã§ããŸãã
{% load widget_tweaks %} {% if no_label != 1 %}{{ field.label_tag }}{% endif %} <div class="b-input {{ div_classes }} {% if field.errors %}error{% endif %}"> {{ field|add_class:'b-input_input' }} </div>
ãšã©ãŒåºåã«ã€ããŠãåãããšãèšããŸãã
django-widget-
{% render_field %}
ã¯ãæ¢åã®å±æ§ã«å±æ§ïŒcssã¯ã©ã¹ãªã©ïŒã远å ããããšãã§ããŸãã
{% render_field form.emails rows="2" class+="b-input_textarea gray" autofocus="" %} {% include "inc/errors.html" with errors=form.emails.errors %}
å©çšå¯èœãªä»æ¥ãããã¯

ãã®ãããã¯ã«ã¯ã仿¥äºçŽå¯èœãª5ã€ã®ã¬ã¹ãã©ã³ããããŸãã 圌ãã¯æ¬¡ã®ããã«ãªããŸãïŒ
restaurants = Restaurant.objects.enabled().free_today_in_city(city).prefetch_related('scenes')[:5]
ã芧ã®ãšããããã®ã¡ãœããã®ãã§ãŒã³ã¯ããã§æ§ç¯ãããŸãïŒ
.enabled().free_today_in_city(city)
ïŒã çµã¿èŸŒã¿ã®dzhangovskyã¢ãããŒã-ãã®ãããªããŒã¹ããããŒãžã£ã«æž¡ã-ã¯ããããèš±å¯ããŸããã ãããŒãžã£ãŒã¡ãœããã¯ãã«ã¹ã¿ã ã¡ãœãããæ¢ã«æããªãQuerySetãè¿ããŸãããã£ã«ã¿ãªã³ã°ã®ããã«ã䜿çšã§ããã¡ãœããã¯1ã€ã ãã§ãã
ãã®å¶éãåé¿ããã«ã¯ã
django-model-utilsã® PassThroughManagerã䜿çšããŠããããŒãžã£ãŒã§ã¯ãªãQuerySetãèšè¿°ããŸãã
class RestaurantQueryset(QuerySet): def enabled(self): return self.filter(enabled=True) def free_today_in_city(self, city): today = city.now().date() return self.filter(city=city).free(today) def free(self, date):
ãã®ãããªãã¹ããã€ãã®ç®¡çè
ããåŸãããŸãïŒç§ã¯åçãéžã°ãªãããšã«æ±ºããŸãã:)ïŒã æšæºãããŒãžã£ãŒã®ä»£ããã«ãããžã§ã¯ãå
šäœã§äœ¿çšããŸãã
ããã¹ãŠè¡šç€ºããã¯ãªãã¯ããŸã
...ãããŠãã¬ã¹ãã©ã³ã®ãªã¹ããå«ãããŒãžã«ç§»åããŸãã ãã®ããŒãžã¯çŽ æŽãããæ€çŽ¢ãã©ãŒã ã§ãããçµæã¯Ajaxã«ãã£ãп޿°ãããŸãã

ç§ã¯jsã«ã€ããŠå°ããªå人çãªãæµè¡ããæã£ãŠããŸãïŒãµã€ãã¯jsãªãã§äœ¿çšã§ããã¯ãã§ãã ããã«ãããéçºæã«ããã€ãã®å©ç¹ãåŸãããŸãã æãããªãã®ã«å ããŠïŒjsã®ãšã©ãŒã¯ãµã€ããåäœäžèœã«ããŸããïŒãããšãã°ããã®ãããªãµã€ãã¯ãã¹ããç°¡åã§ãïŒã»ã¬ã³ãªãã§æã確èªã§ããŸãïŒ+æžãããããããããŸãã
çŸæç¹ã§ã¯ãajaxã«æ¬¡ã®ã¢ãããŒãã䜿çšããŸããajaxãšéåžžã®ãªã¯ãšã¹ãã¯åããã¥ãŒã§åŠçãããŸããå¯äžã®éãã¯ãã³ãã¬ãŒãã«ãããŸãã ãªããªã ajaxãã³ãã¬ãŒãã¯éåžžã®ãã³ãã¬ãŒãã®äžéšã§ãããããéåžžã®ãã³ãã¬ãŒãã«æ¥ç¶ããŸãã éåžžã®ãã¿ãŒã³ïŒ
{% extends 'base.html' %} ... <div class="b-search-results_result"> {% include 'restaurants/ajax/list.html' %} </div> ...
Ajaxãã¿ãŒã³ïŒ
<ul class="b-search-results_result_list"> {% for restaurant in restaurants %} <li>...</li> {% endfor %} </ul>
ãã³ãã¬ãŒãã¯request.is_ajaxïŒïŒã«åºã¥ããŠéžæãããŸãã ã¯ã©ã€ã¢ã³ãã«ã¯å®£èšçãªjsããããéåžžã®htmlãã©ãŒã ãajaxã«å€æã§ããŸãã
def restaurant_list(request, city_slug):
PanGurmanã§ã¯ããããå°ãå®éšããããšã«ããŸããã æåã¯@ajax_templateãã³ã¬ãŒã¿ã§ããã¥ãŒã«ajaxã远å ããŸããã
@ajax_template('restaurants/ajax/list.html') def restaurant_list(request, city_slug): # ... return TemplateResponse(request, 'restaurants/list.html', {...})
ã€ãŸã ãã³ã¬ãŒã¿ã§éåžžã®ãã¥ãŒãã©ããããããŒã¿å±æ§ããã©ãŒã ã«æžã蟌ããšããã©ãŒã ãajaxã«ãªããŸãã
ãããããã®ãªãã·ã§ã³ã¯
'restaurants/(ajax/)?list.html'
ïŒããã¯
'restaurants/(ajax/)?list.html'
ããšã©ãŒã®åå ã§ãïŒãç¹°ãè¿ããŸã
'restaurants/(ajax/)?list.html'
+ãã¥ãŒã«ã¯ããã€ãã®æ»ãç¹ãããããã¹ãŠãajaxã§è¡ãå¿
èŠã¯ãããŸããïŒã€ãŸãããªãã·ã§ã³ã¯åçŽãªãã§ãã¯ãããæªãã§ããã³ã¬ãŒã¿ïŒã
ãããã£ãŠã圌ãã¯@ajax_templateãæåŠãããããŸã§ã®ãšãããã®ãªãã·ã§ã³ã決å®ããŠããŸãã
def restaurant_list(request, city_slug):
showã¯TemplateResponseã®åå«ã§ãããajaxãªã¯ãšã¹ãã®å Žåãæåã«ajaxãµããã©ã«ããŒã§ãã³ãã¬ãŒãã詊è¡ããŸãã
https://gist.github.com/2416695ãåç
§ããŠ
ãã ããã·ã§ãŒã«ã¯ãç§ããã€ãèŠéããŠãããã2ã€ã®æ¹æ³ããããŸãã ããã«ã¯ããã€ãã®åŸ®åŠãªç¹ãããããã¹ãŠãçŽ æŽãããããã§ã¯ãããŸããïŒããšãã°ãåã®ãã¥ãŒããªãã€ã¬ã¯ããè¿ããå Žåã.with_contextã¯èœã¡ãã§ãããïŒããããã䜿çšããããšã¯ããªãå¯èœã§ãïŒãããŠåé¡ã¯ajaxãšã¯ã»ãšãã©é¢ä¿ãããŸããïŒã
ã€ãŸããAjaxãååšããªããã®ããã«ãµã€ããäœæããå¿
èŠã«å¿ããŠãã³ãã¬ãŒãã®å¿
èŠãªéšåããµããã©ã«ããŒã«å
¥ããŠåŸã§è¿œå ããŸãã
äœããèŠã€ãããã¬ã¹ãã©ã³ã§çªã
ã¬ã¹ãã©ã³ã®ããŒãžã«è¡ããŸãã

ãŸããajaxããããŸãïŒæ³šæãã©ãŒã ã§ã¯ãå©çšå¯èœãªæéã¯ajax-requestsã«ãã£ãŠãã§ãã¯ãããŸãïŒããå¥ã®æ¹æ³ã§å®è£
ãããŸã:)
ã«ã¬ã³ããŒã¯ã¯ã©ã€ã¢ã³ãäžã«æ§ç¯ãããããïŒjsããªãå Žåã¯éåžžã®å
¥åãã£ãŒã«ãããããŸãïŒããµãŒããŒããhtmlã§ã¯ãªãjsonãååŸããæ¹ãç°¡åã§ãã
django-tastypieã®å©ããåããŠãç§ã¯ããã«APIãæ§ç¯ãããããéããŠjsonã¯ç®çã®APIã«æž¡ãããŸãã ããã¯ãjsonãæã§è¡šç€ºãããã¥ãŒãèšè¿°ãããããé·ãã¯ãããŸãããããšã«ããAPIã䟿å©ã«ãªããã¹ãããã«ãåºå圢åŒãªã©ã®ããŸããŸãªå©ç¹ãåŸãããŸãã
å¥ã®ãããžã§ã¯ãã§ã¯ãAPIã«django-pistonã䜿çšããŸããã 䞻芳çã«-django-tastypieã®æ¹ãããã§ãã
ãã®ãããªãã¥ãŒã«ãã£ãŠãAPIã®éåžžã«åå§çãªïŒå®å
šã§ã¯ãªãïŒãã«ããèªåçã«çæãããŸãã
def _api_resources(api): resources = {} api_name = api.api_name for name in sorted(api._registry.keys()): resource = api._registry[name] resources[name] = { 'list_endpoint': api._build_reverse_url("api_dispatch_list", kwargs={ 'api_name': api_name, 'resource_name': name, }), 'schema': api._build_reverse_url("api_get_schema", kwargs={ 'api_name': api_name, 'resource_name': name, }), 'doc': resource.__doc__, 'resource': resource } return resources def browse(request, api): resources = _api_resources(api) return TemplateResponse(request, 'tasty_browser/index.html', { 'api': api, 'resources': resources })
ãã³ãã¬ãŒãïŒ
<h1>API {{ api.api_name }}</h1> <table class='tastypie-api'> <tr><th>Resource</th><th>url</th><th>Structure</th><th>Description</th></tr> {% for name, resource in resources.items %} <tr> <td>{{ name }}</td> <td> <a href='{{ resource.list_endpoint }}?format=json'> {{ resource.list_endpoint }}</a> </td> <td> <a href='{{ resource.schema }}?format=json'> {{ resource.schema }}</a> </td> <td> {{ resource.doc }} </td> </tr> {% endfor %} </table>
ããã§èŠãããšãã§ããŸãïŒ
http :
//pangurman.ru/api-docs/æ¯æãã¯
django-robokassa ïŒãã®åŸããã«ãªãã·ã§ã³ã远å ãããŸãïŒãäºçŽã«é¢ããSMSéç¥-
ã€ã¢ãã¹ +ã»ããªãä»ããŠ
è¡ãããŸãã
ãã¡ã€ãã³ã¹

PanGurmanã§ã¯ããŠãŒã¶ãŒã¯è³Œå
¥ã®æ¯æãã«äœ¿çšããå人ã¢ã«ãŠã³ããæã£ãŠããŸãã ããã«ããµã®å©ããåããŠãå人ãæåŸ
ããããã¢ãŒã·ã§ã³ã³ãŒããå
¥åããŠè£å
ã§ããŸãã ãã®åŸãäœããã®æ¹æ³ã§ãããã«ã¡ãœããã远å ãããŸãã
Fowlerãèªãã§ãç§ã¯æ°å¹Žéãå人ã¢ã«ãŠã³ããã®å®è£
ã«æ¬¡ã®ã¢ãããŒãã䜿çšããŠããŸããïŒéé¡ã¯ã©ãã«ãä¿åãããŸããïŒãã ãããã£ãã·ã¥ãããå ŽåããããŸãïŒãããŒã¿ããŒã¹ã®å人ã¢ã«ãŠã³ãã«ãã©ã³ã¶ã¯ã·ã§ã³ãä¿åããŸãã ããã«ãããæäœã®å±¥æŽãèªç¶ã«ååŸãããšã©ãŒããä¿è·ã§ããŸãã
ããšãã°ãæ¯æãã·ã¹ãã ãä»ããŠå人ã賌å
¥ã®æ¯æãã«äžååãªéé¡ãæ¯æãå Žåããã®éé¡ã¯æåã«å人å£åº§ã«å
¥éãããæ¬¡ã«åœŒã¯åž³æ¶ãã詊ã¿ãåæ¹èšå
¥ã¯å€±æãããã®äººã¯è³Œå
¥ããã«å£åº§ã«æ®ã£ããŸãŸã«ãªããŸãã
åæ§ã®ã¢ãã«ãããããžã§ã¯ããããããžã§ã¯ããžãšããããªå€æŽã§ããŸããã
class MoneyTransfer(models.Model): PURCHASE = 'purchase' ROBOKASSA = 'robokassa' INVITE_BONUS = 'invite-bonus' REFUND = 'refund' PROMOCODE = 'promocode' TRANSFER_TYPE_CHOICES = ( (u' ', ( (PURCHASE, u' '), )), (u' ', ( (ROBOKASSA, u' '), (INVITE_BONUS, u' '), (PROMOCODE, u' '), (REFUND, u''), )), ) user = models.ForeignKey(User, verbose_name=u'') amount = models.DecimalField(u'', max_digits=10, decimal_places=2) created_at = models.DateTimeField(u'/ ', auto_now_add=True) comment = models.CharField(u'', max_length=255, blank=True, null=True) transfer_type = models.CharField(u'', max_length=20, null=True, blank=True, choices=TRANSFER_TYPE_CHOICES) content_type = models.ForeignKey(ContentType, null=True, blank=True) object_id = models.PositiveIntegerField(null=True, blank=True) reason = GenericForeignKey('content_type', 'object_id')
ããã§ã¯ãéžæè¢ãæå®ããæ¹æ³ã«æ³šæãæãããšãã§ããŸãã ããã«æžããŸãããéæ³ã®å®æ°ã¯ãªãã誀ã£ãŠinvite_bonusããŒã¿ããŒã¹ã®ä»£ããã«invite_bonusããŒã¿ããŒã¹ã«æžã蟌ãããšã¯ã§ããŸãã-MoneyTransfer.INVITE_BONUSã¯åžžã«åç¬ã§ããã誀ã£ãŠæžã蟌ãŸãããšããã«AttributeErrorã«ãªããŸãïŒãããŠãªãŒãã³ã³ããªãŒãã衚瀺ãããŸãïŒã
ããŒãã«ãäºçŽããŸãããã忢ããŸãããã©ã®ããã«æ©èœããŸããïŒ
ãã«ãããŒãžã«ã¢ã¯ã»ã¹ã
ãŠãã ãã ã ããã¹ãã®äžéšã§ãããã®ããŒãžã§ã¯ãæããã«ãããã°ã©ããŒã®åå ãªãã«ç·šéè
ãç·šéããæ©äŒãäžãããšããã§ãããã

djangoã«ã¯ãã®ããã®ãã©ããããŒãžããããŸãããéåžžã¯å¥ã®ã¢ãããŒãã䜿çšããŸãïŒéåžžã®ãã³ãã¬ãŒãã䜿çšããŠãã¹ãŠã®ããŒãžãéåžžã®ãã¥ãŒã«ããVCSã«ãã¹ãŠãä¿åããç·šéããå¿
èŠãããããã¹ãã
django-flatblocksã®ãããã¯ã§ããŒã¯ããŸãïŒ
<div class="b-text"> {% flatblock "how-it-works" 600 %} </div>
管çè
ã®å Žåãããã¹ãã«ã«ãŒãœã«ãåããããšãç·šéãããªã³ã¯ã衚瀺ãããŸã
ïŒããã¯ããã³ãã¬ãŒãflatblocks / flatblock.htmlãèšå®ããããšã«ããè¡ãããŸãïŒïŒ
{% load url from future %} {% load markup %} {% if user.is_staff %} <div class="b-flatblock-edit"> <a class="flatblock-edit-link markitup-flatblocks-edit-icon" title = " " href='{% url "edit_flatblock" flatblock.pk %}?next={{request.path}}'> </a> {{ flatblock.content|markdown:"video" }} </div> {% else %} {{ flatblock.content|markdown:"video" }} {% endif %}
markdownã®ããŒã¯ã¢ããã¯ãããã¯ã«ä¿åãããŸããç·šéããŒãžã§ã¯ã
django-markitupã®ãŠã£ãžã§ããã衚瀺ããŸãïŒãã¬ãã¥ãŒããïŒã

äžéšã®ããŒã¯ã¢ããã蚱容ããããµã€ãäžã®ãã¹ãŠã®ããã¹ãã¯ãdjango-markitupã䜿çšããŠç·šéãããŸãïŒããšãã°ãåçä»ãã®ã¬ã¹ãã©ã³ã®ã€ã³ã¹ãã¬ãŒã·ã§ã³ãåãã説æïŒã ããŒã¯ããŠã³ãã£ã«ã¿ãŒã¯ãhtmlã¿ã°ã«è§Šããªãããã«æ§æãããŠãããããå¿
èŠã«å¿ããŠãä»»æã®ããŒã¯ã¢ãããããã¹ãã«è¿œå ã§ããŸãã
ãŸããæ¡åŒµæ©èœããã蟌ãŸããŠããŸãïŒ
python-markdown-video ïŒãããã«ãããyoutubeãŸãã¯vimeoãžã®ãªã³ã¯ããããªã«å€æãããŸã-å奜çãªæ¹æ³ã§ãããããoembedãä»ããŠãããè¡ãå¿
èŠããããŸãã
ã¬ã¹ãã©ã³ã®ããã«
ã¬ã¹ãã©ã³ã«ã¯ãç¹å¥ãªããã«ããããããã䜿çšããŠãåŽåæéãå¶åŸ¡ã§ããŸãïŒããŒãã«ãå©çšå¯èœãªå Žåãå©çšã§ããªãå ŽåïŒã ããã«ã¯ãAdminSiteã®å¥ã®ã€ã³ã¹ã¿ã³ã¹ãéããŠå®è£
ãããŸãã ãã¬ã¹ãã©ã³ãããŒãžã£ãŒããšããŠæå®ãããŠãããŠãŒã¶ãŒã¯ããã«ã¢ã¯ã»ã¹ã§ããŸãã 埮åŠãªç¹ã¯ããããã®ãŠãŒã¶ãŒã«is_staffãã©ã°ãä»ããªãããšã§ããããããªããšãéåžžã®ç®¡çããã«ã«ã¢ã¯ã»ã¹ã§ããŸãããããã¯æãŸãããããŸããã ãããŠ-éåžžã®ã«ã¹ã¿ã 管çããã«ã
[æŽèš]
å€ãã®å ŽåãDzhangovka管çè
ã«ã¯æè»æ§ããªããªã©ãšæžãããŠããŸãã -ç§ã¯äººã
ãå
·äœçã«äœãæå³ããã®ãçè§£ã§ããŸããã§ãã:)管çããã«ã¯CRUDãã¬ã€ã¢ãŠããããã³ãã¶ã€ã³ãããã®ãŸãŸãæäŸããŸãã æ£çµ±æŽŸã®ä»£æ¿ãšããŠã圌ãã¯éåžžãããã·ã¥ããŒããæžãããã®ããçš®ã®ãã¬ãŒã ã¯ãŒã¯ãæäŸããŸã-ããã¯CRUDã«åçŽãªãã®ã§ãããdzhangovskoy管çããã«ïŒ django-admin-tools ã nexus ïŒã®ããã®ãã¬ãŒã ã¯ãŒã¯ããããŸãã
äœããã®çš®é¡ã®çžäºäœçšãCRUDã«é©åããªãå Žå-åé¡ã¯ãããŸãããã管çé åå
ã®ã©ãããã§ããã¥ãŒãèšè¿°ããŠããã«ãªã³ã¯ããããšã劚ãããã®ã¯ãããŸããïŒããã§ã¯ãreadonly_fieldsãšlist_displayã䟿å©ãªããšããããããŸã;ãã³ãã¬ãŒãããªãŒããŒã©ã€ãããããšãã§ããŸãïŒã æ°å¹Žéãæ¬²æã®ç®¡çããã«ãæããããæžãçŽãããããããšã¯æ±ºããŠãããŸããã§ãããç§ãã¡ã¯ãã¹ãŠã®ãããžã§ã¯ãã§ããã䜿çšããå€ãã®æéãç¯çŽããŸããã ããããããããžã§ã¯ãã®è©³çްã¯ããã§ããããããšãç§ã¯æ¬åœã«æãããªäœããèŠéããŠããŸããç§ã¯ç¥ããŸããã
[æŽèš]
管çããã«ã§ã¯ãraw_id_fieldsã®ä»£ããã«ãæãããåå
django- salmonellaã®ã¢ããªã±ãŒã·ã§ã³ãç©æ¥µçã«äœ¿çšããŸããããã¯ããŠã£ãžã§ããã«ãææãããæçšãªåäœã䌎ãé¢é£ã¬ã³ãŒããéžæããŸãïŒFKããã³M2Mã®å ŽåïŒ


ãªããžã§ã¯ãã®IDã«å ããŠããã®ååã衚瀺ãããŸãïŒajaxã«ãã£ãп޿°ãããŸãïŒã ååãã¯ãªãã¯ãããšããªããžã§ã¯ãã倿ŽããããŒãžã«ããã«ã¢ã¯ã»ã¹ã§ããŸããããã䟿å©ã§ãã
ãã¹ã
ãã¹ãã®ããã«ã圌ãã¯
å·¥å Žã®å°å¹Ž ïŒãã©ãŒã¯ïŒã䜿ãå§ããŸããã ãã以æ¥ããã¡ã¯ããªãŒããŒã€ã«éåžžã«äŸ¿å©ãªãã®ã1ã€ç»å ŽããŸãããRelatedFactoryã§ãã SubFactoryã®ãããªãã®ã§ããã®å察ã§ãïŒããšãã°ããŠãŒã¶ãŒã®ãã¡ã¯ããªãäœæããŠãããã«ãããã¡ã€ã«ãäœæã§ããŸãïŒã ããã¥ã¡ã³ãã¯
ããã§èªãããšãã§ã
ãŸã ã äŸïŒ
class ProfileF(factory.DjangoModelFactory): FACTORY_FOR = Profile city = factory.SubFactory(CityF) balance = 0 @classmethod def _prepare(cls, create, **kwargs):
ãã¹ãã§ã¯ã次ã®ããã«èšè¿°ã§ããŸãã
user = UserF(profile__balance=100)
ãŠã©ãŒã ã¢ãããšããŠã3çªç®ã®pythonã®ãµããŒãã远å ããŠfactory-boyã§pull-requestãè¡ããŸãããã3çªç®ã®pythonã¯å¥ã®ã¹ããŒãªãŒã®ãããã¯ã§ãïŒDjango 1.4ã«ã¯ããã¹ãã«é¢ãããã1ã€ã®ããªãã¯ããããŸãã ããã©ã«ãã§ã¯ãPBKDF2ã¢ã«ãŽãªãºã ããã¹ã¯ãŒãã®ããã·ã¥ã«äœ¿çšãããŠããŸãã PBKDF2ã§ã¯ãã»ãã¥ãªãã£æ©èœã®1ã€ãäœéã§ãã ããããã»ãã¥ãªãã£ãšã¯å¥ã«ãäœéã¯ããã«äœéãä¿èšŒããŸã:)ã¡ã€ã³ãµã€ãã§ã¯ããã¯ãŸã£ããåé¡ã§ã¯ãããŸããïŒãŠãŒã¶ãŒã¯ãã°ã€ã³ãããã³ã«ç»é²ãããé
å»¶ã¯å°ããã§ãïŒãããã¹ãã§ã¯ãç¹ã«å·¥å Žã䜿çšããå ŽåããããéèŠãªããšã§ããããšã倿ããŸãã-boyãšããã·ã¥ã䜿çšããŠãã¹ã¯ãŒããå²ãåœãŠãããšã«ãããå€ãã®ãŠãŒã¶ãŒãäœæããŸãã
PanGurmanã®å Žåãtest_settings.pyã«ãã®è¡ãã€ã³ã¹ããŒã«ãããšããã¹ãã2åã«å éãããŸããã
PASSWORD_HASHERS = ['django.contrib.auth.hashers.MD5PasswordHasher']