【问题标题】:How to get a Modelform to show fields in a detail page in Django?如何让 Modelform 在 Django 的详细信息页面中显示字段?
【发布时间】:2018-04-04 23:16:47
【问题描述】:

我想要完成的是我将表单从 songcreate 获取到与 Detail.html 相同的 url,这样一个人就可以添加更多歌曲而不必多次离开和返回。最终我希望用AJAX,但还没有进入那个阶段,因为我无法启动表单。我认为它可能只是一些简单的东西,但无法确定它是什么。

Views.py

 class DetailView(generic.DetailView):
        # form_class = SongCreate
        model = Album
        template_name = 'post/detail.html'
    
        def get_form_kwargs(self):
            kwargs = super(SongCreate, self).get_form_kwargs()
            kwargs['user'] = self.request.user
            return kwargs
        def get_object(self, *args, **kwargs):
             pk  =self.kwargs.get('pk')
             obj = get_object_or_404(Album, pk=pk)
             return obj
        def get_context_data( self, *args, **kwargs ):
            context =super(DetailView, self).get_context_data(*args, **kwargs)
            # context['create_form'] = SongCreate()
            # context['create_url'] = reverse_lazy("post:index")
            query = self.request.GET.get("q")
            if query:
                qs = Album.objects.search(query)
            return context

这是使用其 on url 时的歌曲创建视图。它工作得很好,但如果不可能的话,我希望能够在详细信息页面或列表页面中显示此表单。

class SongCreate(CreateView):
        model = Song
        success_url = reverse_lazy('post:index')
        form_class = SongCreate

        def form_valid(self, form):
            if form.is_valid():

---------(这里是验证,为简洁起见略过)--------

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

        def get_form_kwargs(self):
            kwargs = super(SongCreate, self).get_form_kwargs()
            kwargs['user'] = self.request.user
            return kwargs

所以我的主要问题出在这里,出于某种原因,即使字段在其实际页面中完美显示,我也无法正确显示在详细信息页面中。当我设置它时,它只显示表单的轮廓和提交按钮。

Details.html

{% block body %}

      **<!--Form--> HERE IS WHERE I WANT THE FORM-->**
<div class='col-sm-9 '>
     {% if not request.GET.q %}
        <div class=''>

            {% include "post/song_form.html" with form=create_form action_url=create_url btn_title='submit' form_class='SongCreate' %}

        </div>
        <hr/>
    {% endif %}

      <div clas="col-sm-8 col-sm-offset-2" >
               {% for Song in Album.song_set.all %}
                <div class="media">
                  <div class="media-left">
                    <a href="#">
                      {% if object.image %}
                      <img class="media-object" src="..." alt="...">
                      {% endif %}
                    </a>
                  </div>
                  <div class="media-body">
                    {{ song.song_name }}<br/>
                    {{ song.description}}|
                    via {{ Album.timestamp }}
                  </br/>
                    <br>
                 </div>
                </div>
                {% endfor %}
        </div>
      </div>
  </div>
 {% endblock %}

这是我的表格,我使用了一个模型表格,它要求您选择相册,它会显示该人创建的相册,您可以将其附加到该相册,然后对其进行描述。

Forms.py

from django.views.generic import DetailView
from .models import  Song
from .models import  Album
from django import forms

class SongCreate(forms.ModelForm):

    class Meta:
        model = Song
        fields = [
            'album',
            'song_name',
            'description'
        ]
    def __init__(self, user=None, *args, **kwargs):
        self.user = user
        super(SongCreate, self).__init__(*args, **kwargs)
        self.fields['album'].queryset = Album.objects.filter(owner=user)

【问题讨论】:

  • 你的模板目录的结构是什么?
  • post/base, post/song_form.html, post/form-template, form.html

标签: ajax django python-3.x django-forms


【解决方案1】:

试试include "/post/song_form.html"。如果没有前面的斜线,它可能会在您的 details.html 的本地文件夹中查找。

【讨论】:

    【解决方案2】:

    您可以将表单包含在详细视图页面视图中,而不是为详细视图页面和表单创建两个单独的视图。您可以通过添加“mixin”FormMixin 来做到这一点。因此,您将在详细视图中列出您的验证和创建表单逻辑。

    链接到文档here

    from django.views.generic.edit import FormMixin
    
     class DetailView(generic.DetailView,FormMixin):
        model = Album
        template_name = 'post/detail.html'
        form_class = SongCreate
    
        def get_object(self, *args, **kwargs):
             pk  =self.kwargs.get('pk')
             obj = get_object_or_404(Roote, pk=pk)
             return obj
        def get_context_data( self, *args, **kwargs ):
            context =super(DetailView, self).get_context_data(*args, **kwargs)
            # context['create_form'] = SongCreate()
            # context['create_url'] = reverse_lazy("post:index")
            query = self.request.GET.get("q")
            if query:
                qs = Album.objects.search(query)
            return context
      **def form_valid(self, form):
            form.instance.user = self.request.user
            return super().form_valid(form)
    

    【讨论】:

    • 我已经尝试了几次,但得到一个: super(type, obj): obj must be an instance or subtype of type.... 在 cmd: kwargs = super(SongCreate, self ).get_form_kwargs() TypeError: super(type, obj): obj must be an instance or subtype of type 你能进一步解释一下吗?
    • 也许尝试取出 def get_form_kwargs 函数并将用户分配给 def form_valid 函数中的对象。所以在函数中只说 form.instance.user = self.request.user 然后在底部返回 super().form_valid(form) 。我编辑了我的答案。
    猜你喜欢
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-20
    • 2020-01-20
    • 1970-01-01
    • 2018-11-28
    相关资源
    最近更新 更多