5

Hãy nói rằng chúng tôi có một ứng dụng gọi là Closet và nó có một số mô hình:Django: createView với các lĩnh vực trước dân cư và không thể chỉnh sửa theo quy định của chuỗi truy vấn

# closet.models.py 
class Outfit(models.Model): 
    shirt = models.ForeignKey(Shirt) 
    pants = models.ForeignKey(Trouser) 

class Shirt(models.Model): 
    desc = models.TextField() 

class Trouser(models.Model): 
    desc = models.TextField() 

class Footwear(models.Model): 
    desc = models.TextField 

dùng xem chi tiết chung chung, thật dễ dàng để làm cho conf URL để biết chi tiết về từng loại:

#urls.py 
urlpatterns = patterns('', 
    url(r'^closet/outfit/(?P<pk>\d+)$',  DetailView(model=Outfit),  name='outfit_detail'), 
    url(r'^closet/shirt/(?P<pk>\d+)$',   DetailView(model=Shirt),  name='shirt_detail'), 
    url(r'^closet/trouser/(?P<pk>\d+)$',  DetailView(model=Trouser),  name='trouser_detail'), 
    url(r'^closet/footwear/(?P<pk>\d+)$',  DetailView(model=Footwear),  name='footwear_detail'), 
) 

Điều tôi muốn làm tiếp theo là xác định chế độ xem sẽ tạo đối tượng mới cho từng loại. Tôi muốn thực hiện việc này với phiên bản mở rộng là CreateView để có thể xử lý dữ liệu trên các trường được điền trước.

Cụ thể, tôi muốn các hành vi sau đây:

  1. Nếu tôi ghé thăm /closet/outfit/new Tôi muốn để có được một tiêu chuẩn ModelForm cho mô hình Outfit với tất cả mọi thứ trống và tất cả mọi thứ có thể chỉnh sửa.
  2. Nếu tôi truy cập /closet/outfit/new/?shirt=1 Tôi muốn xem tất cả các trường tôi đã thấy trong trường hợp 1) nhưng tôi muốn trường áo sơ mi được điền trước bằng áo với pk = 1. Ngoài ra, tôi muốn trường áo sơ mi được hiển thị là không thể chỉnh sửa. Nếu biểu mẫu được gửi và được coi là không hợp lệ, khi biểu mẫu được hiển thị lại, tôi muốn trường áo sơ mi tiếp tục không thể chỉnh sửa được.
  3. Nếu tôi truy cập /closet/outfit/new/?shirt=1&trouser=2 Tôi muốn xem tất cả các trường tôi đã thấy trong trường hợp 1) nhưng bây giờ cả hai áo sơ mi và các trường quần phải được preopoulated và uneditable. (Tức là chỉ có thể chỉnh sửa trường footwear.)

Nói chung, điều này có thể xảy ra không? I E. chuỗi truy vấn có thể sửa đổi cấu trúc của biểu mẫu được hiển thị theo cách này không? Tôi muốn thực hiện điều này theo cách có thể. Ruột của tôi nói với tôi điều này nên được thực hiện với quan điểm dựa trên lớp học và có lẽ sẽ liên quan đến model_form_factory nhưng tôi không thể có được logic thẳng trong tâm trí của tôi. Cụ thể, tôi không chắc chắn liệu có thể truy cập chế độ xem lớp học theo số request.REQUEST (tức là các thông số request.POST hoặc request.GET) tại thời điểm ModelForm đang được xây dựng.

Có thể chỉ có thể nếu tôi sử dụng các từ khóa chuỗi truy vấn khác nhau cho các trường bị khóa. I E. có lẽ URL cần phải là: /closet/outfit/new/?lock_shirt=1/closet/outfit/new?lock_shirt=1&lock_trouser=2. Có lẽ nếu nó được thực hiện theo cách đó, trình xử lý POST sẽ được cung cấp cả danh sách các trường bị khóa (với mục đích hiển thị biểu mẫu trong trình duyệt) cùng với danh sách thường xuyên của tất cả các trường mô hình nhằm mục đích tạo đối tượng.

Tại sao tôi muốn điều này: Trong mẫu cho footwear_detail tôi muốn để có thể làm cho một thẻ như

<a href="{% url outfit_new %}?footwear={{object.pk}}>Click to create a new outfit with this footwear!</a> 

Nói chung, nó sẽ thực sự hữu ích để có thể tạo liên kết đến hình thức có "cấu trúc" (không chỉ các giá trị) thay đổi tùy thuộc vào chuỗi truy vấn được chuyển.


Đáp lại gợi ý tuyệt vời từ Berislav Lopac:

Vì vậy, tôi đã đi trước và đã làm:

class CreateViewWithPredefined(CreateView): 
    def get_initial(self): 
    return self.request.GET 

này được tôi 90% những gì tôi cần. Nhưng hãy để tôi xác định tình hình nhiều hơn một chút.Giả sử tôi thêm hai trường vào mô hình Trang phục: headgear = models.ManyToManyField('headgear')awesomeness_rating = models.FloatField().

Hai vấn đề:

  1. Nếu tôi ghé thăm /closet/outfit/new/?awesomeness_rating=10 sau đó hình thức của tôi trước lấp đầy với [u'10'] thay vì chỉ làm đầy với 10. Có bộ lọc nào tôi nên sử dụng trong mẫu của mình hoặc một chút xử lý mà tôi có thể thêm vào chế độ xem của mình để làm cho định dạng phù hợp hơn không?
  2. Nếu tôi muốn chỉ định trước một vài mẩu mũ nón, định dạng phù hợp để chuyển những gì cảm thấy giống như danh sách python trong chuỗi truy vấn là gì? I E. tôi có nên làm /closet/outfit/new/?headgear=1,2,3 không? Nếu vậy, Django sẽ tìm ra một cách chính xác rằng tôi muốn chọn trước 3 phần của mũ và các ID đó?

Tiếp tục làm việc về vấn đề này ...

class CreateViewWithPredefined(CreateView): 
    def get_initial(self): 
     initial = super(CreateView, self).get_initial() 
     for k, v in self.request.GET.iterlists(): 
      if len(v) > 1: 
       initial.update({ k : v }) 
      else: 
       initial.update({ k : v[0] }) 
     return initial 

Điều này dường như giết 2 con chim với một đá: dữ liệu số được ép buộc từ unicode để số và nó flattens danh sách khi có thể (như dự định). Cần kiểm tra xem điều này có hoạt động trên các trường có nhiều giá trị hay không.

Trả lời

4

Đó là self.request, ở bất cứ đâu trong CBV. :-)

OK, hãy để tôi làm cho câu trả lời này toàn diện hơn. Về cơ bản, những gì bạn muốn là phương pháp get_initial, được đóng góp bởi FormMixin. Ghi đè lên nó để điền các giá trị ban đầu cho các trường của bạn.

+0

Đây là bước đầu tiên tuyệt vời. Tôi có hai câu hỏi về cách thực hiện điều này. Vui lòng xem các chỉnh sửa đối với bài đăng gốc ở trên. Tôi nghĩ cho mục đích của mình, tôi sẽ đi lên con đường này vì nó có được ý chính. Nhưng trong phạm vi mà những người khác có thể quan tâm đến vấn đề ban đầu: có ai có giải pháp cho câu hỏi ban đầu ... thay vì chỉ điền trước biểu mẫu với dữ liệu ban đầu, có cách nào để các trường được điền sẵn thực sự hiển thị hay không bị khóa? – 8one6

+0

Một cách là thêm thuộc tính 'readonly' vào phần tử đầu vào, có thể trong phương thức' get_form' của khung nhìn. Bạn có thể lấy các trường 'request.GET' (hoặc thậm chí tốt hơn sử dụng' get_initial' của bạn để tránh trùng lặp mã) và sửa đổi widget của mỗi trường có giá trị ở đó. –

+0

Cảm ơn. Tôi khá mới và tôi vẫn gặp sự cố với định dạng unicode. Tôi hiểu rằng tất cả các mục trong QueryDict mà tôi nhận được từ 'request.GET' sẽ được định dạng thành chuỗi Unicode. Có cách nào chung để chuyển đổi một unicode sang kiểu dữ liệu gốc python của nó? Vì vậy, nếu tôi làm '/ closet/outfit/new /? Awesomeness_level = 10' Tôi muốn đảm bảo rằng trường có sẵn với 10 thay vì [u'10] ... – 8one6

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