django-extra-views 将 InlineFormSet 字段值公开为 get_context_data()



我想访问InlineFormSet的字段,以便在视图中使用。

下面是一个基于 https://django-extra-views.readthedocs.io/en/latest/views.html#createwithinlinesview-and-updatewithinlinesview 的示例:

from extra_views import InlineFormSet, CreateWithInlinesView,

class ItemsInline(InlineFormSet):
model = Item

class TagsInline(InlineFormSet):
model = Tag

class OrderCreateView(CreateWithInlinesView):
model = Order
inlines = [ItemsInline, TagsInline]
def get_success_url(self):
return self.object.get_absolute_url()

如何在get_context_data((forms_valid((方法中公开 InlineFormSet 字段?警告:下面的代码失败了!

class OrderCreateView(CreateWithInlinesView):
[... see above ...]
def get_context_data(self, **kwargs):
context = super(OrderCreateView, self).get_context_data(**kwargs)
if self.request.POST:
context['items'] = ItemsInline(self.request.POST)
context['tags'] = TagsInline(self.request.POST)
else:
context['items'] = ItemsInline()
context['tags'] = TagsInline()
return context
def forms_valid((self, form, inlines):
[...]    
return super(OrderCreateView, self).forms_valid(form, inlines)

我用这个模型重现了你的例子:

STATUS_CHOICES = (
(0, 'Placed'),
(1, 'Charged'),
(2, 'Shipped'),
(3, 'Cancelled'),
)
class Order(models.Model):
name = models.CharField(max_length=255)
date_created = models.DateTimeField(auto_now_add=True)
date_modified = models.DateTimeField(auto_now=True)
action_on_save = models.BooleanField(default=False)

class Item(models.Model):
item_name = models.CharField(max_length=255)
sku = models.CharField(max_length=13)
price = models.DecimalField(decimal_places=2, max_digits=12, db_index=True)
order = models.ForeignKey(Order, related_name='items', on_delete=models.CASCADE)
status = models.SmallIntegerField(default=0, choices=STATUS_CHOICES, db_index=True)
date_placed = models.DateField(default=now, null=True, blank=True)
def __unicode__(self):
return '%s (%s)' % (self.item_name, self.sku)

class Tag(models.Model):
tag_name = models.CharField(max_length=255)
content_type = models.ForeignKey(ContentType, null=True, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField(null=True)
content_object = GenericForeignKey('content_type', 'object_id')
def __unicode__(self):
return self.tag_name

网址:

from django.conf.urls import url
from .views import OrderCreateView, OrderUpdateView
urlpatterns = [
url(r'^inlines/new/$', OrderCreateView.as_view()),
url(r'^inlines/(?P<pk>d+)/$', OrderUpdateView.as_view()),
]

形式:

from django import forms
from .models import Order, Item

class OrderForm(forms.ModelForm):
class Meta:
model = Order
fields = ['name']
def save(self, commit=True):
instance = super(OrderForm, self).save(commit=commit)
if commit:
instance.action_on_save = True
instance.save()
return instance

class ItemForm(forms.ModelForm):
flag = forms.BooleanField(initial=True)
class Meta:
model = Item
fields = ['item_name', 'sku', 'price', 'order', 'status']

视图:

from django.contrib.contenttypes.models import ContentType
from extra_views import InlineFormSet, CreateWithInlinesView, UpdateWithInlinesView
from extra_views.generic import GenericInlineFormSet
from .forms import OrderForm
from .models import Item, Order, Tag

class ItemsInline(InlineFormSet):
model = Item
fields = ['item_name', 'sku', 'price', 'order', 'status']

class TagsInline(GenericInlineFormSet):
model = Tag
fields = ['tag_name']

class OrderCreateView(CreateWithInlinesView):
model = Order
fields = ['name']
context_object_name = 'order'
inlines = [ItemsInline, TagsInline]
template_name = 'extra_views/order_and_items.html'
def get_success_url(self):
return '/inlines/%i' % self.object.pk

class OrderUpdateView(UpdateWithInlinesView):
model = Order
form_class = OrderForm
inlines = [ItemsInline, TagsInline]
template_name = 'extra_views/order_and_items.html'
def get_success_url(self):
return ''
  • OrderCreateView中,您无法读取TagItem中的记录get_context_data方法,因为它们尚未创建。

  • OrderCreateView中,您可以读取forms_valid后的所有记录 方法像往常一样。

  • OrderUpdateView中,您可以读取get_context_data方法就像在forms_valid方法中一样。

它看起来像这样:

class OrderCreateView(CreateWithInlinesView):
# ... 
def get_context_data(self, **kwargs):
data = super(OrderCreateView, self).get_context_data(**kwargs)
from pprint import pprint
pprint(self.request.POST)  # there is only post data here
return data
def forms_valid(self, form, inlines):
instance = super(OrderCreateView, self).forms_valid(form, inlines)
ct = ContentType.objects.get_for_model(self.model)
print('all items', [item.item_name for item in self.object.items.all()])  # items
print('all tags', [tag.tag_name for tag in
TagsInline.model.objects.filter(content_type=ct, object_id=self.object.id)])  # tags
return instance
class OrderUpdateView(UpdateWithInlinesView):
# ... 
def get_context_data(self, **kwargs):
context = super(OrderUpdateView, self).get_context_data(**kwargs)
ct = ContentType.objects.get_for_model(self.model)
print('all items', [item.item_name for item in self.object.items.all()])  # items
print('all tags', [tag.tag_name for tag in
TagsInline.model.objects.filter(content_type=ct, object_id=self.object.id)])  # tags
return context

最新更新