Django 2.0 มันก็จะเหนื่อยๆหน่อย

django

#1

ด้วยความที่ django upgrade version เมื่อไหร่ ก็เรา up ตามกันไป แก้นิดแก้หน่อยตามภาษาแต่ตอนนี้ 1.x -> 2.0 มันก็ชัดเจนว่า breaking changes สำคัญมาแล้ว

เอาง่ายๆ สำหรับคนจะ upgrade ไป django 2.0 จะต้องทำอะไรก่อน และจะต้องแก้อะไรหลังจากเปลี่ยนแล้ว

ก่อนจะไป 2.0

สิ่งที่ต้องรู้

  • django 2.0 supports python 3.4, 3.5, 3.6 เท่านั้น :wave::wave: 2.7 :wave::wave:
  • ForeignKey, OneToOneField จะต้องมี on_delete เป็น argument บังคับ #1 option มีอะไรบ้างดูตามนี้
    สิ่งที่เลวร้ายที่สุดของการเปลี่ยนนี้ จะส่งผลกระทบกับคนที่ใช้ django ก่อน 1.8 เพราะว่า พวก migration files นั่นก็คือ มีปัญหาด้วย วิธีแก้:
    • บ้างก็บอกให้ squashmigrations ก่อนจะได้เหลือ file น้อยๆ อันนี้ใช้ได้กับคนที่สร้าง app แบบอิสระต่อกันครับ ไม่มี cross dependencies ระหว่าง app ก็น่าจะ squash แล้วแก้ที่ file น้อยลงเยอะมาก เหลือแค่ 1 file ต่อ app งี้ #2 Yes, it’s required in migrations ​as documented. Consider squashing migrations so you don’t have many to update.
    • แต่ถ้ามี cross dependencies แนะนำครับ ว่า ให้เพิ่ม on_delete ให้ครบก่อนที่จะเปลี่ยนไป django 2.0 แล้วก็ migrate ให้ครบทั้งหมดก่อน :arrow_right: จากนั้นก็ลบมันทิ้งไปให้หมด :exploding_head: เริ่มต้น migrate ใหม่ที่ 2.0 แล้วชีวิตจะมีความสุขครับ
      :bangbang: ไม่ใช่ไม่มีปัญหา เพราะต้อง TRUNCATE TABLE django_migrations เอง แล้วเมื่อย้ายไป django 2.0 หมดแล้วก็ต้องเริ่มต้นด้วย ./manage.py migrate --fake ก่อน
  • python2 syntax ก็ต้องแก้กันไปนะครับ
    • xrange --> range เฉยๆ
    • unicode ไม่มีละ เพราะเป็น str หมด ไม่ก็เป็น bytes เลยซึ่งก็กลายเป็นต้องระวังใหม่
    • str.decode() ไม่ได้ละ จะต้องเป็น str.encode() แทน
    • และอื่นๆ… :carousel_horse::ferris_wheel::roller_coaster:

หลังมาซบกับ 2.0

MIDDLEWARE_CLASSES --> MIDDLEWARE

SessionAuthenticationMiddleware ตัดทิ้งไปมีเป็น default เลย

from django.core.urlresolvers import reverse --> from django.urls import reverse

django.shortcuts.render_to_response() --> django.shortcuts.render()

user.is_authenticated() --> user.is_authenticated

user.is_anonymous() --> user.is_anonymous

@register.assignment_tag --> @register.simple_tag

URLConf

อันนี้เปลี่ยนเยอะหน่อย

from django.conf.urls import url, include --> from django.conf.urls import path, re_path, include

url(r'^movie/', include('movie.urls', namespace="movie")) --> url(r'^movie/', include('movie.urls'))

แต่ใน movie.urls.py ก็ต้องมี

app_name = "movie"
urlpatterns = [ ... ]

ของใหม่ก็มี เรียกว่า คนไม่ชอบ regex คงจะชอบใจ django.urls.path

from django.urls import include, path

urlpatterns = [
    path('index/', views.index, name='main-view'),
    path('bio/<username>/', views.bio, name='bio'),
    path('a/<slug:title>/', views.article, name='article-detail'),
    path('a/<slug:title>/<int:section>/', views.section, name='article-section'),
]

ส่วน url() เดิมก็กลายเป็น alias ของ re_path() ซึ่งก็ตามปกติ url() ก็จะตายไปใน release ต่อๆไป แก้ได้ก็แก้ครับ เพราะแค่เปลี่ยนชื่อ

เท่าที่เห็นหลักๆ ก็น่าจะประมาณนี้ ที่ยังแก้อีกหลายส่วนก็ไล่ๆกันไป ส่วนใหญ่จะเป็นเรื่องของ py2 -> py3 ซะมากกว่า