2016-03-05 2 views
1

У меня есть FormView, который генерирует обзор объекта (с которым он в основном связан), а затем связывает его с объектом и сохраняет его, когда форма завершена.Persist Django FormView Data

Проблема, с которой я сталкиваюсь, заключается в том, что у меня нет возможности удержать данные объекта, к которому я хочу подключиться. Это означает, что мне нужно «искать его» для контекста (рендеринг шаблона) для правильной обработки (для создания ссылок) и для успеха (для создания соответствующего обратного URL-адреса.

Есть ли лучший способ привязки обзор для объекта? Или еще лучше, есть ли способ сохранить данные формы, которые мне не хватает?

EDIT: Извините, что дизайнер оформления был отправлен. Я удалил этот метод, потому что SO жаловался на слишком много кода и я не думал, что это было важно ... Я, должно быть, пропустил декоратор

class ReviewCreate(FormView): 
    template_name = 'food/item_add_review.html' 
    form_class = ReviewForm 
    review_item = None 


    def get_context_data(self, **kwargs): 
     context = super(ReviewCreate, self).get_context_data(**kwargs) 

     item_modelname = self.kwargs.get('model') 
     item_model = apps.get_model('food',item_modelname) 
     review_item = get_object_or_404(item_model,pk=self.kwargs.get('pk')) 

     context['item'] = review_item 

     return context 

    def form_valid(self, form): 
     item_modelname = self.kwargs.get('model') 
     item_model = apps.get_model('food',item_modelname) 
     review_item = get_object_or_404(item_model,pk=self.kwargs.get('pk')) 

     r = form.save(commit=False) 

     r.content_object=review_item 
     r.save() 

     return super(ReviewCreate, self).form_valid(form) 

    def get_success_url(self): 
     item_modelname = self.kwargs.get('model') 
     item_model = apps.get_model('food',item_modelname) 
     review_item = get_object_or_404(item_model,pk=self.kwargs.get('pk')) 

     return reverse('pkitem', kwargs = {'pk': review_item.id, 'model':item_modelname},) 

ответ

1

Вид является объектом права, поэтому вы просто назначаете вам r к переменным экземпляра, i e "to self" (this is thread-safe). Пример:

class ReviewCreate(FormView): 
    template_name = 'food/item_add_review.html' 
    form_class = ReviewForm 

    @method_decorator(login_required) # Use a class level mixin instead 
    def get_context_data(self, **kwargs): 
     return super(
      ReviewCreate, 
      self 
     ).get_context_data(
      item=self.review_item, 
      **kwargs 
     ) 

    def lookup_review_item(self): 
     self.item_modelname = self.kwargs.get('model') 
     item_model = apps.get_model('food', self.item_modelname) 
     self.review_item = get_object_or_404(
      item_model, 
      pk=self.kwargs.get('pk') 
     ) 

    def dispatch(self, request, *args, **kwargs): 
     # lookup performed here to be set for both GET and POST 
     self.lookup_review_item() 
     return super(ReviewCreate, self).dispatch(request, *args, **kwargs) 

    def form_valid(self, form): 
     r = form.save(commit=False) 
     r.content_object=self.review_item 
     r.save() 
     return super(ReviewCreate, self).form_valid(form) 

    def get_success_url(self): 
     return reverse(
      'pkitem', 
      kwargs = { 
       'pk': self.review_item.id, 
       'model': self.item_modelname 
      }, 
     ) 
+0

Я попытаться изменить к себе. * В get_context_data бит переменные не торчат ... Хотя это более изящным есть и очевидная причина того, что не работает? – Ewanw

+0

Если self.review_item не получил set, get_context_data поднимет AttributeError. Я бы дважды проверил шаблон. –

0

get_context_data должен всегда возвращать контекстный словарь. Не имеет смысла использовать с ним декоратор login_required, потому что это означает, что он может вернуть ответ перенаправления.

Вместо этого было бы лучше украсить метод dispatch. В вашем dispatch вы можете установить атрибуты экземпляра.

class ReviewCreate(FormView): 

    @method_decorator(login_required) 
    def dispatch(self, request, *args, **kwargs): 
     self.item_modelname = self.kwargs.get('model') 
     self.item_model = apps.get_model('food',item_modelname) 
     self.review_item = get_object_or_404(item_model,pk=self.kwargs.get('pk')) 
     return super(ReviewCreate, self).dispatch(request, *args, **kwargs) 

Тогда в ваших других методов, вы можете получить доступ к атрибутам, например:

def get_context_data(self, **kwargs): 
     context = super(ReviewCreate, self).get_context_data(**kwargs) 
     context['item'] = self.review_item 
     return context 
0

form_valid() метод по умолчанию для FormView перенаправляет к URL успеха и инициализирует форму. Вы можете сделать данные формы сохраняются путем переопределения form_valid():

def form_valid(self, form): 
    return super(YourFormView, self).get(form) 

будет переадресован на ваш успех URL с (ограниченная) форма, имеющая отправленные данные. Форма добавляется в контекст, поэтому вы можете использовать данные в своем шаблоне или в своем представлении по своему усмотрению.

(Django версии 1.11.7)

Смежные вопросы