我想在另一种表单中显示一个表单。
例如我有这些模型:
class Measure(models.Model):
length = models.ForeignKey(Statistics, related_name='Length', null=True, blank=True)
surface_area = models.ForeignKey(Statistics, related_name='Surface area+', null=True, blank=True)
section_area = models.ForeignKey(Statistics, related_name='Section area+', null=True, blank=True)
volume = models.ForeignKey(Statistics, related_name='Volume', null=True, blank=True)
diameter = models.ForeignKey(Statistics, related_name='Diameter', null=True, blank=True)
class Statistics(models.Model):
total = models.FloatField('Total', null=True, blank=True)
avg = models.FloatField('Average', null=True, blank=True)
min = models.FloatField('Minimum', null=True, blank=True)
max = models.FloatField('Maximum', null=True, blank=True)
standard_deviation = models.FloatField('Standard deviation', null=True, blank=True)
然后我将这些表格与之前的模型相对应:
class StatisticsForm(forms.ModelForm):
class Meta:
model = Statistics
fields = '__all__'
class MeasureForm(forms.ModelForm):
class Meta:
model = Measure
fields = '__all__'
# Here I have to say that the right form for each field is the StatisticForm
表单中的ForeignKey呈现为一个组合框,包括另一个表中的所有对象(在我的情况下是Statistics表),我想用一个StatisticsForm对象替换组合框,这样我就可以控制方式了渲染统计对象
非常感谢。
答案 0 :(得分:2)
您的数据库方案和模型设计不正确,无法解决手头的问题。你正在定义一个"有很多"关系在错误的方向。一个Measurement
应该有多个Statistics
,但是一个Statistics
不应该有多个Measurement
。
由于您的模型现在已设置,ForeignKey
位于关系的错误一侧。你应该这样做:
class Measure(models.Model):
def save(self,*args,**kwargs):
result = super(Measure, self).save(*args,**kwargs)
Statistics.objects.create(name='length', measurement=self)
Statistics.objects.create(name='section', measurement=self)
Statistics.objects.create(name='surface', measurement=self)
Statistics.objects.create(name='volume', measurement=self)
Statistics.objects.create(name='diameter', measurement=self)
return result
要像访问当前代码一样Statistics
访问Measurement
,您可以添加几个@property
个快捷方式:
class Measure(models.Model):
@property
def length(self):
return self.statistics_set.get(name='length')
@property
def section(self):
return self.statistics_set.get(name='section')
@property
def surface(self):
return self.statistics_set.get(name='surface')
@property
def volume(self):
return self.statistics_set.get(name='volume')
@property
def diameter(self):
return self.statistics_set.get(name='diameter')
class Statistics(models.Model):
name = models.CharField(max_length=10)
measurement = models.ForeignKey('Measurement')
total = models.FloatField('Total', null=True, blank=True)
avg = models.FloatField('Average', null=True, blank=True)
min = models.FloatField('Minimum', null=True, blank=True)
max = models.FloatField('Maximum', null=True, blank=True)
standard_deviation = models.FloatField('Standard deviation', null=True, blank=True)
一旦修复了对象之间的关系,问题就变得更容易解决了。 ForeignKeyFields
不是形式中的Statistics
,而是成为正确的相关对象,这些对象通常由django处理。
正如评论中提到的@solarisssmoke,您正在寻找表单集。以下是django documentation展示如何实现所需目标的示例:
有问题的模型:
class Author(models.Model):
name = models.CharField(max_length=100)
title = models.CharField(max_length=3, choices=TITLE_CHOICES)
birth_date = models.DateField(blank=True, null=True)
def __str__(self): # __unicode__ on Python 2
return self.name
class Book(models.Model):
name = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
使用inlineformset_factory
创建所需的formset的视图:
from django.forms import inlineformset_factory
def manage_books(request, author_id):
author = Author.objects.get(pk=author_id)
BookInlineFormSet = inlineformset_factory(Author, Book, fields=('title',))
if request.method == "POST":
formset = BookInlineFormSet(request.POST, request.FILES, instance=author)
if formset.is_valid():
formset.save()
# Do something. Should generally end with a redirect. For example:
return HttpResponseRedirect(author.get_absolute_url())
else:
formset = BookInlineFormSet(instance=author)
return render(request, 'manage_books.html', {'formset': formset})
如果性能成为一个问题,请查看prefetch_related
以提高性能。