Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Django App-gehoben

Django App-gehoben

Was Packages auf dem PyPI für Python sind, sind Pluggable Apps für Django.
Aus den Bereichen RESTful API, Formulare, Sicherheit, CSS/SCSS/JS Handling, Softwaretesting, Taskqueue, Ajax, Suche, Datenbankschemamigration und Authentifizierung wird jeweils ein populäres Beispielpackage kurz vorgestellt. Der Fokus liegt bewusst nicht auf Details. Gezeigt werden grob die Funktionsweise, Installation und ein paar Erfahrungen aus dem praktischen Einsatz.

Aufzeichnung:
http://pyvideo.org/video/1425/django-app-gehoben
https://www.youtube.com/watch?v=dOaJdo1km-o

Frank Becker

October 31, 2012
Tweet

Other Decks in Programming

Transcript

  1. Motivation http://www.djangopackages.com @robert_winslow: So much of software development is about

    discovering and grokking the wheels someone else already made for you. Mittwoch, 31. Oktober 12
  2. • shell_plus • create_app (von Dia UML file) • export_emails

    (aller User) • graph_models (graphviz) • Jobs scheduling • TimeStampedModel ABS (created, modified) • Field Extensions (AutoSlugField, CreationDateTimeField, ModificationDateTimeField, UUIDField, EncryptedCharField, EncryptedTextField) • print_settings • sqldiff • sqlcreate • RunServerPlus (werkzeug) • RunProfileServer django-extensions Mittwoch, 31. Oktober 12
  3. django-braces Class Based Generic Views sind cool, aber... • LoginRequiredMixin

    • PermissionRequiredMixin • MultiplePermissionsRequiredMixin • SuperuserRequiredMixin • UserFormKwargsMixin • UserKwargModelFormMixin • SuccessURLRedirectListMixin • SetHeadlineMixin • CreateAndRedirectToEditView • SelectRelatedMixin • StaffuserRequiredMixin • JSONResponseMixin • AjaxResponseMixin Mittwoch, 31. Oktober 12
  4. django-braces from django.views.generic import TemplateView from braces.views import LoginRequiredMixin, PermissionRequiredMixin

    class SomeSecretView(LoginRequiredMixin, TemplateView): template_name = "path/to/template.html" def get(self, request): return self.render_to_response({}) class SomeProtectedView(LoginRequiredMixin, PermissionRequiredMixin, TemplateView): permission_required = "auth.change_user" template_name = "path/to/template.html" Mittwoch, 31. Oktober 12
  5. django-bootstrap http://paltman.com/2012/08/23/twitter-bootstrap-and-ajax/ # only adding this request.is_ajax() block to the

    existing views.py @login_required def message_list(request): if request.is_ajax(): data = { "html": render_to_string("messages/_message_list.html", { "messages": request.user.messages.all() }, context_instance=RequestContext(request)) } return HttpResponse(json.dumps(data), mimetype="application/json") return render(request, "messages/message_list.html", { "messages": request.user.messages.all(), "form": MessageForm() }) # messages.html {% extends "messages/base.html" %} {% block body %} <h1>Your Messages</h1> <p class="lead">Here is a stream of your messages.</p> <{% include "messages/_message_form.html with form=form %}> {% include "messages/_message_list.html" with messages=messages %} {% endblock %} {% block extra_body %} <script src="{% static "js/bootstrap-ajax.js" %}"></script> {% endblock %} Mittwoch, 31. Oktober 12
  6. #_message_list.html <div class="messages" data-refresh-url="{% url messages %}"> {% for message

    in messages %} {% include "messages/_message.html" with message=message %} {% endfor %} </div> #_message_form.html {% load bootstrap_tags %} <form action="{% url message_list %}" method="post" id="message-form" class="form ajax" data-replace="#message-form" data-refresh=".messages,.message-count"> {% csrf_token %} {{ form|as_bootstrap }} <div class="form-actions"> <button type="submit" class="btn btn-primary">Submit</button> </div> </form> Mittwoch, 31. Oktober 12
  7. django-secure • SECURE_SSL_REDIRECT • SECURE_HSTS_SECONDS • SECURE_FRAME_DENY • SECURE_CONTENT_TYPE_NOSNIFF •

    SECURE_BROWSER_XSS_FILTER • SESSION_COOKIE_SECURE + SESSION_COOKIE_HTTPONLY • python manage.py checksecure Mittwoch, 31. Oktober 12
  8. ... Running djangosecure.check.sessions.check_session_cookie_httponly... OK Running djangosecure.check.djangosecure.check_security_middleware... OK Running djangosecure.check.djangosecure.check_sts... FAIL

    You have not set a value for the SECURE_HSTS_SECONDS setting. If your entire site is served only over SSL, you may want to consider setting a value and enabling HTTP Strict Transport Security (see http://en.wikipedia.org/wiki/Strict_Transport_Security). Running djangosecure.check.djangosecure.check_sts_include_subdomains... FAIL You have not set the SECURE_HSTS_INCLUDE_SUBDOMAINS setting to True. Without this, your site is potentially vulnerable to attack via an insecure connection to a subdomain. Running djangosecure.check.djangosecure.check_frame_deny... FAIL Your SECURE_FRAME_DENY setting is not set to True, so your pages will not be served with an 'x-frame-options: DENY' header. Unless there is a good reason for your site to be served in a frame, you should consider enabling this header to help prevent clickjacking attacks. ... Mittwoch, 31. Oktober 12
  9. South • Muss man haben. • DB Schemamigration • python

    manage.py schemamigration APP --init • python manage.py schemamigration APP --auto Mittwoch, 31. Oktober 12
  10. django-compressor # base.html template <!-- Le styles --> <link href="{{

    STATIC_URL }}css/ahz/bootstrap.css" rel="stylesheet"> {% compress css %} <link rel="stylesheet" href="{{ STATIC_URL }}css/ahz/custom.scss" type="text/x-scss"> {% endcompress css %} # settings.py COMPRESS_PRECOMPILERS = ( ('text/x-scss', '/.../bin/pyscss -C -o {outfile} {infile}'), ) # rendered html <link rel="stylesheet" href="/static/CACHE/css/0f5901951cca.css" type="text/css" /> Mittwoch, 31. Oktober 12
  11. django-floppyforms • Widgets rendered per Template • HTML5 Widgets •

    crispy-forms + floppyforms kombinierbar #from django import forms import floppyforms as forms Mittwoch, 31. Oktober 12
  12. django-tastypie # myapp/api.py # ============ from tastypie.resources import ModelResource from

    myapp.models import Entry class EntryResource(ModelResource): class Meta: queryset = Entry.objects.all() # urls.py # ======= from django.conf.urls.defaults import * from tastypie.api import Api from myapp.api import EntryResource v1_api = Api(api_name='v1') v1_api.register(EntryResource()) urlpatterns = patterns('', # The normal jazz here then... (r'^api/', include(v1_api.urls)), ) • RESTful API kinderleicht • Batteries included Mittwoch, 31. Oktober 12
  13. tastypie-queryset-client Get >>> client = Client("http://api.server.com/your/v1/") >>> client.your.objects.get(name="your") <your: {u"id":

    u"1", u"name": u"your", u"status": u"any"}> Count >>> client = Client("http://api.server.com/your/v1/") >>> client.your.objects.count() 100 Filter >>> client = Client("http://api.server.com/your/v1/") >>> client.your.objects.filter(name="your") <QuerySet <class 'Response'> (3/3)> Mittwoch, 31. Oktober 12