2015-04-22 18 views
19

Tôi đã thêm trường mới, không thể rỗng vào mô hình Django của mình và đang cố gắng sử dụng di chuyển để triển khai thay đổi đó. Làm cách nào để tôi đặt giá trị mặc định để sử dụng cho các mô hình hiện tại là một số chức năng của các mô hình đó chứ không phải là hằng số?Di chuyển Django Thêm trường bằng mặc định làm chức năng của kiểu

Ví dụ: giả sử trước đây tôi có trường created_on và tôi vừa thêm trường updated_on có giá trị tôi muốn đặt ban đầu vào kiểu created_on của mô hình. Làm thế nào tôi sẽ làm điều này trong một di cư?

Đây là những gì tôi đang cố gắng để bắt đầu với:

migrations.AddField(
     model_name='series', 
     name='updated_as', 
     field=models.DateTimeField(default=????, auto_now=True), 
     preserve_default=False, 
    ), 

Trả lời

14

Bạn cần phải làm điều đó trong hai cuộc di cư. Trước hết, thêm trường của bạn, nhưng làm cho nullable. Tạo tệp di chuyển như thường lệ. Sau đó thiết lập trường của bạn để không nullable và chạy makemigrations một lần nữa, nhưng không lauch di chuyển được nêu ra. Mở di chuyển thứ hai và xác định hàm ở trên cùng:

def set_field_values(apps, schema_editor): 
    # use apps.get_model("app_name", "model_name") and set the defualt values 

sau đó, trong tệp di chuyển của bạn có danh sách hoạt động. Trước hoạt động lĩnh vực alter làm thêm

RunPython(set_field_values) 

và nó nên làm điều đó

23

Tôi chỉ học được cách để làm điều này với một sự chuyển đổi duy nhất!

khi chạy makemigrations django sẽ yêu cầu bạn đặt mặc định một lần. Xác định bất cứ điều gì bạn có thể ở đây để giữ cho nó hạnh phúc, và bạn sẽ kết thúc với sự di cư AddField bạn đã đề cập.

migrations.AddField(
    model_name='series', 
    name='updated_as', 
    field=models.DateTimeField(default=????, auto_now=True), 
), 

Thay đổi này hoạt động một thành 3 hoạt động:

  1. ban đầu làm cho nullable lĩnh vực, vì vậy các cột sẽ được thêm vào.
  2. gọi hàm để điền trường nếu cần.
  3. thay đổi trường (bằng AlterField) để làm cho trường không thể rỗng (như ở trên, không có mặc định).

để bạn kết thúc bằng thứ gì đó tương tự.

migrations.AddField(
    model_name='series', 
    name='updated_as', 
    field=models.DateTimeField(null=True, auto_now=True), 
), 
migrations.RunPython(set_my_defaults), 
migrations.AlterField(
    model_name='series', 
    name='updated_as', 
    field=models.DateTimeField(auto_now=True), 
), 

với chức năng của bạn định nghĩa là một cái gì đó như:

def set_my_defaults(apps, schema_editor): 
    Series = apps.get_model('myapp', 'Series') 
    for series in Series.objects.all().iterator(): 
     series.updated_as = datetime.now() + timedelta(days=series.some_other_field) 
     series.save() 

trừ, bạn biết đấy, không khủng khiếp.

Các vấn đề liên quan