我需要清理内联formset中的特定字段,我无法弄清楚如何做到这一点.
我尝试过使用formsets def clean(self)方法,但不知道在哪里保存清理后的值.如果我尝试将清理后的值设置为" forms[0].data['field']我的QueryDict实例是不可变的"错误.
在"正常"形式中,它通过使用def clean_fieldXY(self)我的方法工作return cleaned_value.
请帮忙.
我有一个包含许多外键字段的模型,例如带有字段'type','level','color','intensity'的模型Product(只是一个通用示例).
然后,我有一个页面,使用Type表单编辑给定类型的所有产品,产品作为内联formset,并可选择使用内联添加其他产品extra=10.
我觉得非常奇怪的是,每次当我输出模板上的一个外键选择字段时,Django会查询数据库以获取选项(每次).
例如:
{% for form in formset %}
{{ form.level }}
{{ form.color }}
{{ form.intensity }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
有20个产品(和10个空的额外表格),上面的代码select * from ...从级别,颜色和强度共发出30 个查询(使用Django调试工具栏显示),其中3应该就足够了.这些选项不太可能在请求中改变,但即使它们确实如此,我绝对不希望一些新添加的选项仅出现在最后5个表单中.
有没有办法优化我的模型/表单/视图/模板,以便数据库不会被不必要地敲打?
-
免责声明:我对django和python相对较新,并且不禁想到必须有办法以某种方式解决这个问题.
我正在创建一个示例,以了解有关使用SessionWizard的内联表单集的更多信息.最后,我想集成动态表单集,以便在提交之前通过模板添加和删除单个表单.但是,当第二种形式中没有数据时,它不能像常规ModelForm那样进行验证.
SessionWizard中是否有需要覆盖的方法?这是Django内在处理的东西吗?
非常感谢指导和实例.
models.py
class Parent(models.Model):
name = models.CharField(max_length=256)
def __unicode__(self):
return name
class Child(models.Model):
name = models.CharField(max_length=256)
parent = models.ForeignKey(Parent)
def __unicode__(self):
return name
Run Code Online (Sandbox Code Playgroud)
urls.py
test_forms = [['parent', ParentForm],['child', ChildFormSet]]
urlpatterns = patterns('example.views',
url(r'^$', TestWizard.as_view(test_forms)),
)
Run Code Online (Sandbox Code Playgroud)
forms.py
class ParentForm(ModelForm):
class Meta:
model = Parent
class ChildForm(ModelForm):
class Meta:
model = Child
exclude = ('parent',)
ChildFormSet = inlineformset_factory(Parent, Child, extra=1)
class TestWizard(SessionWizardView):
"""
This WizardView is used to create multi-page forms and handles all the
storage and validation stuff using …Run Code Online (Sandbox Code Playgroud) 我有一个Django项目,有2个模型,a Structure和Bracket,Bracket有一个ForeignKey到一个结构(即一对多,一个结构有许多括号).我TabularInline为管理站点创建了一个,这样就可以在Structure上找到一个Brackets表.我添加了一个自定义formset和一些自定义clean方法来进行一些额外的验证,你不能让一个Bracket与同一个结构上的另一个Bracket冲突.
管理员看起来像这样:
class BracketInline(admin.TabularInline):
model = Bracket
formset = BracketInlineFormset
class StructureAdmin(admin.ModelAdmin):
inlines = [
BracketInline
]
admin.site.register(Structure, StructureAdmin)
Run Code Online (Sandbox Code Playgroud)
在BracketInlineFormset刚刚有干净的方法:
class BracketInlineFormset(forms.models.BaseInlineFormSet):
def clean(self):
… my clean code here …
Run Code Online (Sandbox Code Playgroud)
一切正常,验证工作.
但是现在我想写一些unittest来测试我复杂的formset验证逻辑.
我首次尝试验证已知良好的值是:
data = {'form-TOTAL_FORMS': '1', 'form-INITIAL_FORMS': '0', 'form-MAX_NUM_FORMS': '', 'form-0-field1':'good-value', … }
formset = BracketInlineFormset(data)
self.assertTrue(formset.is_valid())
Run Code Online (Sandbox Code Playgroud)
但是这不起作用并引发异常:
======================================================================
ERROR: testValid (appname.tests.StructureTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/paht/to/project/tests.py", line 494, in testValid
formset = BracketInlineFormset(data)
File "/path/to/django/forms/models.py", …Run Code Online (Sandbox Code Playgroud) 我对Django和Python还很陌生,所以请耐心等待。我正在尝试创建一个如下所示的表格时间表。
时间表表格:
预期结果
我想要实现的是,当我调用特定的时间表时,我应该获取所有相关的时间表详细信息数据并以与工作日期/项目组合相关的所有小时数都在同一行中的方式填充上面的表格,并且相关小时数是放置在相应的工作代码下(即在图片中,第 1 行在“规范”下有 8 小时,第 2 行在 RnR 下有 12 小时)
问题
现在如何设置初始值以根据工作日/项目组合的工作代码在每一行中填充正确的小时单元格(与模型字段无关)?
其次,如果同一工作日/项目的时间是分开的(例如标准 4 小时和 Annu 4 小时),我该如何处理?我如何把它放在同一行?如果我可以使用字典来填充这会很容易吗?
由于我在 10/80/20... 字段的表单中没有任何初始数据,因此我无法检查是否删除了任何小时数,以便我也可以删除该记录。
我开始质疑自己,我的内联森林方法在这种情况下是否有效?
所以底线是我如何在这个表单中填充这些不相关的表单字段?
我愿意接受任何方法或想法来实现这一目标,并感谢您的帮助。
如果您发现我做错了什么,请随时纠正我,以便我学习。
代码
模型.py
class Workcode(models.Model):
workcode = models.PositiveSmallIntegerField()
workcode_description = models.CharField(max_length=20)
workcode_short = models.CharField(max_length=4)
workcode_serial = models.SmallIntegerField()
class Project(models.Model):
project = models.CharField(max_length=10)
class Employee(models.Model):
name = models.CharField(max_length=10)
class WeekendDate(models.Model):
weekenddate = models.DateField(unique=True)
class Timesheet(models.Model):
employee = models.ForeignKey(Employee)
weekenddate = models.ForeignKey(WeekendDate)
class Meta:
unique_together = ('employee', 'weekenddate')
class …Run Code Online (Sandbox Code Playgroud) 我在 Django 中使用内联表单集,并且对于每个显示一个“额外”表单的项目,用于添加另一个对象。
现有对象的表单具有“删除”复选框,用于删除该对象,这是有道理的。
但“额外”表单也有这些“删除”复选框......这没有任何意义,因为没有任何东西可以删除。Django 管理中的内联表单不会为“额外”表单显示这些“删除”复选框。
如何删除“额外”内联表单上的这些复选框?
我的模板的内联表单集部分是这样的(GitHub 上的简化完整版本):
{% for bookimage_form in form.forms %}
{% for hidden_field in bookimage_form.hidden_fields %}
{{ hidden_field.errors }}
{% endfor %}
{{ bookimage_form.as_table }}
{% endfor %}
Run Code Online (Sandbox Code Playgroud)
这是似乎多余的“删除”复选框:
当我使用一个formset这既can_order和can_delete我能够得到所有被删除的形式.deleted_forms和所有非删除表格(顺序).ordered_forms。
如果我使用不使用的表单集,can_order我将不再有权访问.ordered_forms(它会引发异常)。有没有一种简单的方法来获取未删除的表单列表?
我能找到的最接近的是手动创建它:
[form for form in formset.forms if not formset._should_delete_form(form)]
Run Code Online (Sandbox Code Playgroud)
但是,这是使用“隐藏”方法,似乎很奇怪还没有内置的东西。
我正在尝试使用以下代码将自定义字段添加到InlineFormset,但字段不会显示在Django Admin中.InlineFormset是否也被锁定以允许此操作?我的打印"ding"测试按预期触发,我可以打印出form.fields并在那里看到它们,但实际的字段永远不会在管理员中呈现.
admin.py
from django.contrib import admin
import models
from django.forms.models import BaseInlineFormSet
from django import forms
from forms import ProgressForm
from django.template.defaultfilters import slugify
class ProgressInlineFormset(BaseInlineFormSet):
def add_fields(self, form, index):
print "ding"
super(ProgressInlineFormset, self).add_fields(form, index)
for criterion in models.Criterion.objects.all():
form.fields[slugify(criterion.name)] = forms.IntegerField(label=criterion.name)
class ProgressInline(admin.TabularInline):
model = models.Progress
extra = 8
formset = ProgressInlineFormset
class ReportAdmin(admin.ModelAdmin):
list_display = ("name", "pdf_column",)
search_fields = ["name",]
inlines = (ProgressInline,)
admin.site.register(models.Report, ReportAdmin)
Run Code Online (Sandbox Code Playgroud) 我有一个作者模型和书籍模型.用户可以修改给定作者的所有书籍的属性.我希望能够为每本书显示错误,而不是列出顶部的所有错误,我该怎么做?
楷模
from django.db import models
from django.forms import ModelForm, Textarea
from django import forms
class Author(models.Model):
fname = models.CharField(max_length=100)
lname = models.CharField(max_length=100)
def fullname(self):
return '%s %s' % (self.fname, self.lname)
fullname = property(fullname)
def __unicode__(self):
return self.fullname
class Books(models.Model):
author = models.ForeignKey(Author)
title = models.CharField(max_length=50)
publisher = models.CharField(max_length=50)
edition = models.CharField(max_length=50)
comment = models.TextField()
def __unicode__(self):
return self.title
Run Code Online (Sandbox Code Playgroud)
视图
def author_books_edit(request, author_id):
a = get_object_or_404(Author, pk=author_id)
authorsbooks = a.books_set.all()
bookformset = inlineformset_factory(Author, Books, can_delete=True, can_order=True, exclude=('company',), extra=1)
formset = …Run Code Online (Sandbox Code Playgroud) 我正在尝试复制Django管理员中的内联,以便在我自己的非管理员ModelForm上的FKd模型上添加相关模型.特别是,当您使用StackeAdminInline并获得Javascript的"+ Add another XXX"位以添加更多相关模型时.
如果管理员可以这样做,那一定是可能的,但我找不到一个项目,其中包含如何执行此操作的示例.谁能指点我的东西?我正在使用Crispy Forms,尽管如果需要也很高兴.我确实看到了https://github.com/runekaagaard/django-crispy-forms-fancy-formsets,但好像这不是Crispy维护者的首选,并且认为必须有更多的Djangoic方式来做到这一点管理员可以做到这一点.
谢谢!
inline-formset ×10
django ×9
django-forms ×4
python ×4
formset ×3
admin ×1
field ×1
forms ×1
inlines ×1
validation ×1