在基于类的创建和更新视图中将父级 PK 传递到 ModelForm

问题描述 投票:0回答:1

我正在将基于功能的视图更新为基于类的视图,并且在重新建立活动和书籍之间的链接时遇到问题。我的图书模型有一个指向营销活动的外键链接。

campaign = models.ForeignKey(Campaign, on_delete=models.DO_NOTHING)

我有一个 ModelForm,我在其中设置了 Campaign_id,并希望从 CreateView 中获取它。

class BookForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        author = kwargs.pop('author', None)
        campaign_id = kwargs.pop('campaign_id', None)
        super(BookForm, self).__init__(*args, **kwargs)
        if campaign_id:
            self.fields['campaign_id'].initial = campaign_id

     campaign_id = forms.CharField(widget=forms.HiddenInput())

我按照this使用dispatch和get_form_kwargs,我的CreateView看起来像

class BookCreateView(generic.CreateView):
    model = Book
    template_name = 'PromoManager/book_form.html'
    form_class = BookForm
    success_url = '/profile'
    campaign_id = None

    # Retrieves the campaign_id from url
    def dispatch(self, request, *args, **kwargs):
        self.campaign_id = kwargs.get("pk")
        return super().dispatch(request, *args, **kwargs)

    ## Sends building id to the form
    def get_form_kwargs(self, *args, **kwargs):
        kwargs = super().get_form_kwargs(*args, **kwargs)
        kwargs["campaign_id"] = self.campaign_id
        return kwargs

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['campaign'] = Campaign.objects.get(pk=self.campaign_id)
        context['title_label'] = "Create"
        return context

    def form_valid(self, form):
        instance = form.save(commit=False)
        instance.author = self.request.user
        instance.campaign = Campaign.objects.get(id=form.cleaned_data['campaign_id'])
        instance.save()
        form.save_m2m()
        return super().form_valid(form)

但是它破坏了UpdateView,它依赖于与更新视图URL上传递的PK是书pk相同的形式。我的 UpdateView 看起来像:

class BookUpdateView(generic.UpdateView):
    model = Book
    template_name = 'PromoManager/book_form.html'
    form_class = BookForm
    success_url = '/profile'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['title_label'] = "Update"
        return context

    def form_valid(self, form):
        print(form)
        form.save(commit=True)
        return super().form_valid(form)

    def form_invalid(self, form):
        print(form.errors)

如何将营销活动 ID 或实例传递到表单以在创建时填充它,然后在任何更新期间维护该值。该值不应更改。 TY

python django modelform
1个回答
0
投票

所以,我有一个解决方案,但仍然有兴趣听听它是一个好的解决方案还是有问题。我已使用 get_initial 将值传递到 ModelForm。

BookForm(ModelForm) 的初始化如下所示:

def __init__(self, *args, **kwargs):
    super(BookForm, self).__init__(*args, **kwargs)

    self.fields['campaign_id'].initial = kwargs['initial']['campaign'].id
    self.fields['author_name'].initial = kwargs['initial']['user'].first_name + " " + kwargs['initial']['user'].last_name

CreateView 看起来像:

def get_initial(self):
    campaign = Campaign.objects.get(pk=self.kwargs.get('pk'))
    return {'campaign': campaign, 'user': self.request.user}

最后 UpdateView 看起来像:

def get_initial(self):
    book = Book.objects.get(pk=self.kwargs.get('pk'))
    return {'campaign': book.campaign, 'user': self.request.user }

我的问题是,这是否是获取更新数据的最有效方法,因为它已经在表单实例中(或者会吗?)

© www.soinside.com 2019 - 2024. All rights reserved.