2011-06-25 45 views
7

Tôi đang cố gắng sử dụng lớp CreateView chung để xử lý các biểu mẫu cho một tập hợp các mô hình được kế thừa từ cùng một lớp cơ sở.Django: các tham số dựa trên lớp tham số

class BaseContent(models.Model): 
    ... 

class XContent(BaseContent): 
    ... 

class YContent(BaseContent): 
    ... 

Để giữ mọi thứ, tôi muốn xác định một lớp CreateView sẽ xử lý tất cả các lớp kế thừa từ BaseContent.

Các mẫu url để xem đó là:

url(r'^content/add/(?P<model_name>\w+)/$', ContentCreateView.as_view(), name='content_add') 

Something như thế này nên làm việc:

class ContentCreateView(CreateView): 
    template_name = 'content_form.html' 

    def get_model(self, request): 
     # 'content' is the name of the application; model_name is 'xcontent', 'ycontent', ... 
     return ContentType.objects.get_by_natural_key('content', self.model_name) 

Nhưng tôi nhận được ngoại lệ này:

ContentCreateView is missing a queryset. Define ContentCreateView.model, ContentCreateView.queryset, or override ContentCreateView.get_object(). 

đề nghị này không dường như giữ như tôi không sẵn sàng để thiết lập một thuộc tính lớp học như model hoặc queryset t o giữ cho mô hình tạo ra năng động. Việc ghi đè get_object dường như không có liên quan để tạo đối tượng.

Tôi đã cố gắng ghi đè get_queryset() nhưng phương pháp này không chấp nhận thông số request và cũng không có quyền truy cập vào self.model_name xuất phát từ mẫu url.

Ngắn câu chuyện ngắn, làm cách nào tôi có thể tạo một CreateView sử dụng biểu mẫu động dựa trên thông số được truyền từ url?

Cảm ơn.

+0

Tôi nghĩ rằng yêu cầu và model_name sẽ được đặt làm biến mẫu, vì vậy bạn có thể tự .request và self.model_name bên trong phương thức get_queryset(). Không thử suy nghĩ đó. – bmihelac

+1

có, Xem lớp học là tổ tiên của CreateView đặt kwargs từ url làm biến mẫu. nhưng 'self.model_name' không thể truy cập vào' get_queryset() 'vì nó đến từ một mixin khác trong khi' self.request' là. nếu tôi vượt qua tên mô hình như là một tham số 'get' tôi sẽ có thể làm những gì tôi muốn nhưng nó sẽ không được tốt đẹp. imo, cách kế thừa và các mixin được tổ chức trong các khung nhìn dựa trên lớp và thiếu tài liệu làm cho nó rất phức tạp để theo dõi các phương thức và các thuộc tính của lớp. – omat

+1

Bạn không thể chỉ tạo các lớp biểu mẫu cho từng mô hình và trên phương thức get_form_class của 'ModelFormMixin' để lấy biểu mẫu có liên quan cho khung nhìn dựa trên các tham số yêu cầu? – vimukthi

Trả lời

1

Bạn có thể thiết lập các thuộc tính model từ urls.py của bạn, tùy thuộc vào các url được gọi là:

url(r'^content/add/x/$', 
    ContentCreateView.as_view(model=XContent), name='x_content_add'), 
url(r'^content/add/y/$', 
    ContentCreateView.as_view(model=YContent), name='y_content_add') 

tôi thừa nhận nó không hoàn hảo như bạn đang lặp đi lặp lại cho mình một chút, nhưng vì vậy bạn có lợi thế của việc có các tên khác nhau cho cùng một chế độ xem, tùy thuộc vào kiểu máy! Bên cạnh đó bạn cũng có thể làm điều gì đó tương tự với việc ghi đè form_class ...

+0

as_view() dường như không chấp nhận đối số. cách bạn đề xuất tăng: 'as_view() lấy chính xác 1 đối số (2 đã cho)'. tôi đã sửa đổi mẫu url theo cách này: 'url (r '^ add/x/$', ContentCreateView.as_view(), {'queryset': XContent.objects.all()}) 'nhưng kwarg dường như không được truyền cho cá thể lớp:' ContentCreateView thiếu một tập queryset'. – omat

+0

Xin lỗi lỗi của tôi, tất nhiên bạn phải vượt qua nó như kwargs, không phải là dict, chỉnh sửa câu trả lời! –

+0

cảm ơn bạn đã cập nhật, không sao. tôi hy vọng nó sẽ được tài liệu sớm, mặc dù nó không phải là dễ dàng với nhiều cấp độ thừa kế nhiều. – omat

1

Đã xảy ra sự cố này trong một thời gian, nhưng đã tìm ra giải pháp. Bạn cần ghi đè phương thức công văn, được định nghĩa trong as_view() (django.views.generic.base), như sau:

class ContentCreateView(CreateView):  
    def dispatch(self, request, *args, **kwargs): 
     for app in ['foo', 'bar']: 
      model = models.get_model(app, kwargs['modelname']) 
      if model: 
       self.model = model 
       break 

     return super(GenericEdit, self).dispatch(request, *args, **kwargs) 
    ... 
    ... 
Các vấn đề liên quan