2015-08-10 1 views
0

У меня есть стиль формы редактирования, который я использовал для использования, где позволяет пользователю отправить форму, путем указания формы, в которой она редактирует экземпляр, а не делает новая рк:, позволяющий представить форму модели, где у модели есть требуемое поле, передавая представления класса на основе класса Django

edit_form = PrivateProfileForm(data=request.POST, instance=profile) 

приложение в вопросе имеет модель с необходимой, уникальной областью, которая должна быть (URL):

class Article(models.Model): 
    url   = models.CharField(max_length=256, unique=True) 
    title  = models.CharField 
    user = models.ForeignKey(User, null=True, blank=True) 

в представлениях на основе класса, несколько попыток передать форму instance = article fail, хотя и молча, с моей последней неудачей пытаюсь ING form.instance = article_in_question

Посмотреть сообщение:

class ArticleUpdateView(UpdateView): 
    model   = Article 
    form_class  = EditArticleForm 
    template_name = 'index/edit_article.html' 

    def get_context_data(self, **kwargs): 
     context = super(ArticleUpdateView, self).get_context_data(**kwargs) 
     context['tags'] = Tag.objects.all() 
     return context 

    def add_tags(self, article, tags_to_add): 
     for tag in tags_to_add: 
      article.tags.add(tag) 

    def form_invalid(self, **kwargs): 
     return self.render_to_response(self.get_context_data(**kwargs)) 

    def post(self, request, *args, **kwargs): 
     self.object = None 
     article_in_question = Article.objects.get(pk=self.kwargs['pk']) 
     print article_in_question 
     form_class = self.get_form_class() 
     form_name = 'form' 
     form = self.get_form(form_class) 
     if form.is_valid(): 
      tags_chosen = request.POST.getlist('selected_tags') 
      form.instance = article_in_question 
      article = form.save(commit=False) 
      article.save() 
      self.add_tags(article, tags_chosen) 
      return self.form_valid(form) 
     else: 
      return self.form_invalid(**{form_name: form}) 

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

Моя текущая форма редактирования и исходная форма для сравнения:

class ArticleForm(forms.ModelForm): 
    class Meta: 
     model = Article 
     fields = ('url', 'title', 'user') 

    url  = forms.CharField(widget=forms.TextInput(attrs={'placeholder': 'required'}), 
        max_length=256, label='URL', required=True)  
    title = forms.CharField(widget=forms.TextInput(attrs={"placeholder": "I'll grab the page's title"}), 
        max_length=256, label='Title', required=False) 
    user = forms.CharField(widget=forms.HiddenInput()) 

    def clean(self): 
     try: 
      title = self.cleaned_data['title'] 
      url = self.cleaned_data['url'] 
      title = process_title(url) 
      self.cleaned_data['title'] = title 
     except: 
      pass 
     username = self.cleaned_data['user'] 
     user = User.objects.get(username=username) 
     self.cleaned_data['user'] = user 
     super(ArticleForm, self).clean() 
     return self.cleaned_data 


class EditArticleForm(forms.ModelForm): 
    url  = forms.CharField(required=False) 
    title = forms.CharField(required=False) 
    class Meta: 
     model = Article 
     fields = ('url', 'title') 

Я называю форме такой же, как при создании объектов, и в представлении, article_in_question выходит как реальная статья. Если вам интересно, шаблон выглядит следующим образом (тот же вид, что работает при создании объекта):

<form id="article_form" method="post" action="" enctype="multipart/form-data"> 
    {% csrf_token %} 
    {{ form|bootstrap }} 
    {% for tag in tags %} 
     <div style="display:inline-block;" > 
      <input type="checkbox" name="selected_tags" id="option{{tag.id}}" value={{tag.name}} /> 
      <label for="option{{tag.id}}">{{tag.name}}</label> 
     </div> 
    {% endfor %} 
<br/> 
<input type="submit" name="submit" value="Edit article"/> 

после просмотра в оболочке:

In [5]: v = ArticleUpdateView() 

In [8]: v.form_class 
Out[8]: index.forms.EditArticleForm 

In [14]: a = Article.objects.create(url='fake.com', title="fake") 

In [15]: a 
Out[15]: <Article: fake> 

In [19]: form =v.form_class(instance=a) 

In [20]: form 
Out[20]: <EditArticleForm bound=False, valid=Unknown, fields=(url;title)> 

Я очень удивлен тем, что:

form_class = self.get_form_class() 
    form_class.instance = article_in_question 
    print form_class.instance 
    form_name = 'form' 
    form = self.get_form(form_class) 

не работал. Печать form_class.instance показала, что соответствующая статья прикреплена к этому классу формы.

Как я могу указать форму, в которой он работает с экземпляром в этих классах?

ответ

0

Nevermind. Если кто-то еще изучает классы, Django хочет узнать об этом, обратите внимание, что form = self.get_form(form_class) делает что-то внутренне, что перезаписывает instance до None. Решение было:

form_class = self.get_form_class() 
    form_name = 'form' 
    form = self.get_form(form_class) 
    form.instance = article_in_question 

способ увидеть, что эти хитрые взгляды класса действительно происходит в IPython и захватывая один как

In [22]: from index.views import ArticleUpdateView 

In [23]: v = ArticleUpdateView() 

затем играть с ее позиций непосредственно:

In [24]: v. 
v.add_tags     v.get_template_names 
v.as_view     v.http_method_names 
v.content_type    v.http_method_not_allowed 
v.context_object_name  v.initial 
v.dispatch     v.model 
...etc... 

это оказалось гораздо более эффективным, чем чтение документов в течение нескольких часов; в то время как они очень тщательны, во многих случаях, как представляется, отсутствуют практические примеры

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

  • Нет связанных вопросов^_^