Django:Add&单击按钮,使用类视图删除额外的输入字段

时间:2016-07-02 22:58:34

标签: django django-models django-forms django-templates django-views

我要做的是以下内容:User将使用必要信息创建production(也称为播客剧集),直到此时为止production_id此查询的id)。这个想法是,当用户到达ChapterMark模板时,他将能够create several timestamps指出他/她在整个剧集中正在讲话的某些主题。 chaptermark_id创建One-To-Many,因为它是id并且使用此views.py我可以在该集中添加尽可能多的时间戳。考虑到这一点,这是针对这种情况的最佳方法,以及如何在我的表单,类视图和模板中实现它?

提前致谢

这是我的from django.http import HttpResponseRedirect, Http404, HttpResponseForbidden from django.shortcuts import render, get_object_or_404 from django.views.generic import View, RedirectView, TemplateView from django.contrib.auth.decorators import login_required from django.contrib.auth.mixins import LoginRequiredMixin from .forms.client_setup import ClientSetupForm from .forms.podcast_setup import PodcastSetupForm from .forms.episode_info import EpisodeInfoForm from .forms.image_files import EpisodeImageFilesForm from .forms.wordpress_info import EpisodeWordpressInfoForm from .forms.chapter_marks import EpisodeChapterMarksForm from .forms.show_links import ShowLinksForm from .forms.tweetables import TweetablesForm from .forms.clicktotweet import ClickToTweetForm from .forms.schedule import ScheduleForm from .forms.wordpress_account import WordpressAccountForm from .forms.wordpress_account_setup import WordpressAccountSetupForm from .forms.wordpress_account_sortable import WordpressAccountSortableForm from .forms.soundcloud_account import SoundcloudAccountForm from .forms.twitter_account import TwitterAccountForm from producer.helpers import get_podfunnel_client_and_podcast_for_user from producer.helpers.soundcloud_api import SoundcloudAPI from producer.helpers.twitter import TwitterAPI from django.conf import settings from producer.models import Client, Production, ChapterMark, ProductionLink, ProductionTweet, Podcast, WordpressConfig, Credentials, WordPressSortableSection, \ TwitterConfig, SoundcloudConfig from django.core.urlresolvers import reverse from producer.tasks.auphonic import update_or_create_preset_for_podcast class EpisodeChapterMarksView(LoginRequiredMixin, View): form_class = EpisodeChapterMarksForm template_name = 'fc/forms_chapter_marks.html' def get(self, request, *args, **kwargs): initial_values = {} user = request.user # Lets get client and podcast for the user already. if not existent raise 404 client, podcast = get_fc_client_and_podcast_for_user(user) if client is None or podcast is None: raise Http404 # The production_id or the chaptermark_id must be passed on teh KWargs production_id = kwargs.get('production_id', None) chaptermark_id = kwargs.get('chaptermark_id', None) if chaptermark_id: chaptermark = get_object_or_404(ChapterMark, id=chaptermark_id) production = chaptermark.production elif production_id: production = get_object_or_404(Production, id=production_id) chaptermark = None initial_values['production_id'] = production.id if chaptermark is not None: initial_values['chaptermark_id'] = chaptermark_id initial_values['start_time'] = chaptermark.start_time initial_values['title'] = chaptermark.title form = self.form_class(initial=initial_values) return render(request, self.template_name, {'form': form}) def post(self, request, *args, **kwargs): form = self.form_class(request.POST) if form.is_valid(): # lets get the data production_id = form.cleaned_data.get('production_id') chaptermark_id = form.cleaned_data.get('chaptermark_id') start_time = form.cleaned_data.get('start_time') title = form.cleaned_data.get('title') # Get production production = get_object_or_404(Production, id=production_id) # if a chaptermark existed, we update, if not we create if chaptermark_id is not None: chaptermark = ChapterMark.objects.get(id=chaptermark_id) else: chaptermark = ChapterMark() chaptermark.start_time = start_time chaptermark.title = title chaptermark.production = production chaptermark.save() return HttpResponseRedirect(reverse('fc:episodeshowlinks')) return render(request, self.template_name, {'form': form})

chaptermark.py

from django import forms class EpisodeChapterMarksForm(forms.Form): production_id = forms.IntegerField(widget=forms.Field.hidden_widget, required=False) chaptermark_id = forms.IntegerField(widget=forms.Field.hidden_widget, required=False) start_time = forms.TimeField(required=False) title = forms.CharField(max_length=200) 表格

chaptermark

{% extends "fc/base.html" %} {% load crispy_forms_tags %} {% block content %} <div class="progress"> <div class="progress-bar progress-bar-striped progress-bar-success active" role="progressbar" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100" style="width: 50%"> <span class="sr-only">50% Complete</span> </div> </div> <div class="panel panel-default box-shadow--16dp col-sm-6 col-sm-offset-3"> <div class="panel-body"> <div class='row'> <div class='col-sm-12'> {% if title %} <h1 class='{% if title_align_center %}text-align-center{% endif %}'>{{ title }}<!-- : {{ get.clientsetup.company_name }} --></h1> {% endif %} {% if subtitle %} <h3 class='{% if subtitle_align_center %}text-align-center{% endif %}'>{{ subtitle }}</h4> {% endif %} <h5>Chapter Marks</h5> <form method='POST' action=''>{% csrf_token %} {{ form|crispy }} <hr/> <button type="submit" class="btn btn-primary box-shadow--6dp"><i class="fa fa-chevron-right pull-right"></i> Continue </button> </form> </div> </div> </div> </div> {% endblock %} 模板:

views.py

---------------------- UPDATE --------------------- ----

@login_required def episodechaptermarks(request): title = 'Podcast' title_align_center = True subtitle = 'Setup | Add Episode' subtitle_align_center = True form = ChapterMarksForm(request.POST or None) context = { "title": title, "subtitle": subtitle, "form": form } if form.is_valid(): instance = form.save(commit=False) start_time = form.cleaned_data.get("start_time") title = form.cleaned_data.get("title") instance.start_time = start_time instance.title = title instance.user = request.user instance.save() return render(request, "pod_funnel/forms_chapter_marks.html", context) else: return render(request, "pod_funnel/forms_chapter_marks.html", context)

ModelForm

from django import forms from producer.models import ChapterMark class ChapterMarksForm(forms.ModelForm): class Meta: model = ChapterMark fields = ['start_time', 'title'] def clean_start_time(self): start_time = self.cleaned_data.get('start_time') return start_time def clean_title(self): title = self.cleaned_data.get('title') return title

{{1}}

1 个答案:

答案 0 :(得分:1)

从本质上讲,您的production对象有一系列timestamp s通过FK返回。您需要production级别的一组CRUD视图。我们假设您的模型已经创建。根据我的经验,我想指出的一些事情,我认为我会指出你正确的方向。

  1. 除非绝对必要,否则在创建镜像模型的表单对象时永远不要使用Form类;您正在引入对不必要的复杂性的需求并为错误打开大门。使用ModelForm,可以直接从视图中将对象保存到数据库,并帮助您管理清理,验证等。此外,这些可以轻松地与各种类型的通用视图进行网格化。

  2. 对于这种关系(具有与给定对象相关的给定类型的不同数量的模型对象的模型对象)Django提供了强大但困难的inlineformset_factory。这会为此类关系创建一系列内联表单。

  3. 所以你有一个模型(production)和另一个相关的模型(timestamp)。您需要同时保存这些,可能执行清理或验证,并且实际上为这种关系提供CRUD功能。为此,您可以从头开始创建一个复杂的视图,您可以使用django-extra-views及其通用CBV用于带有内联的模型。您可以继承CreateWithInlinesViewUpdateWithInlinesView。为什么?大多数Django开发人员都同意模板很难实现。

  4. 那么,为了给你一个如何做到这一点的简化版

    from extra_views.advanced import CreateWithInlinesView, InlineFormSet, UpdateWithInlinesView
    
    
    class TimeStampsInline(InlineFormSet):
        model = models.TimeStamp
        form = TimeStampForm # If you haven't created a custom ModelForm, can also specify "fields= ['field_1','field_2',...] and the CBV will create a ModelForm
        extra = 0
    
    
    class ProductionCreate(CreateWithInlinesView):
        model=models.Production
        inlines = [TimeStampsInline]
        success_url = reverse('production-list') # the url to return to on successful create
        exclude = ['created_by'] # render all fields except this in form
        template_name = 'myapp/update.html'
    
    class ProductionUpdate(UpdateWithInlinesView):
        model=models.Production
        inlines = [TimeStampsInline]
        success_url = reverse('production-list')
        exclude = ['created_by']
        template_name = 'myapp/update.html'
    

    您的模板必须使用formset在规范中构建;那里有文档和教程。

    这已经有很多要消化的了,但你可能会得到一般的想法。不要从头开始制造马;)