首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Django formset_factory诉modelformset_factory vs inlineformset_factory

Django formset_factory诉modelformset_factory vs inlineformset_factory
EN

Stack Overflow用户
提问于 2018-10-28 19:09:42
回答 1查看 5.9K关注 0票数 28

表单在Django中可能很复杂。Formset可以使您想退出Django。我就在这一点上。

不同的用例和使用哪一个的考虑?

我正在寻找一些关于何时使用每个工厂的更好的指导,因为它们似乎取决于您何时知道什么类型的表单、字段,以及您是否要创建、编辑或删除(完全独立的表单或父模型)。我已经阅读了许多演练,但我很难看到更大的图景,尤其是当我试图从基于函数的视图转移到基于类的视图时。

下面是一些带有假设/限制的伪代码,以帮助您理解差异。它可能有助于提供psuedocode,例如与Formset一起使用什么样的表单(ModelForm或正则的),或者应该从表单中得到什么,因为这似乎是创建带有关系的表单的一种趋势。

假设你有一些模型:

代码语言:javascript
复制
class Dish(models.Model):
    name = models.CharField(max_length=50)


class Meal(models.Model):
    name = models.CharField(max_length=50)
    dishes = models.ManyToManyField(Dish,
                                    # through='OPTIIONALMealDishIntermediaryClassTable',
                                    related_name="meal")

class Reservation(models.Model):
    date = models.DateTimeField()
    greeting = models.CharField(max_length=255)
    meal = models.OneToOneField(Meal, on_delete=models.CASCADE)


class MealPhotos(models.Model):
    photo = models.OneToOneField(Photo, on_delete=models.CASCADE, related_name='mealPhoto')
    meal = models.ForeignKey(Meal, on_delete=models.CASCADE)
    # optional, so a photo can be attached to a dish if the picture is just of the dish
    dish = models.ForeignKey(Dish, blank=True, null=True, on_delete=models.CASCADE)

如果您想要创建一个新的Meal,您需要同时发送一个Reservation

  • 你会用哪一家工厂?
  • 它是否取决于表单是否都是ModelForms?(意思是您将如何处理分配Meal及其Reservation)
  • 假设:
    • 在这个阶段,您知道它是哪个Meal,但是您仍然必须在同一时间/相同的视图中创建一个Reservation
    • 你不知道你要做哪个Dish,因为预订会告诉你。
    • MealPhotos还不存在,因为这顿饭还没有准备好。
    • 您希望在相同的窗体/屏幕上创建膳食和预订

然后,根据Reservation的说法,添加一些菜肴:

  • 你会用哪一家工厂?
  • 它是否取决于这些表单是否都是ModelForms
  • 假设:
    • 在这个阶段,您知道它是哪个Meal,并且您有一个Reservation
    • 您将根据Reservation为饭菜分配菜肴,并且您有足够的信息可以这样做,并且可以轻松地使用ModelForm,但不是必需的。

后来,吃这道菜的人想拍几张照片,你不知道他们会拍多少张

  • 你会用哪一家工厂?
  • 它是否取决于这些表单是否都是ModelForms
  • 假设:
    • 我们会要求他们至少拿两张
    • 我们可以访问MealReservationDishes
    • 可以选择将照片分配给Dish

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-11-10 00:24:08

3家formset工厂之间的区别基本上是:

  • formset_factory允许您将一组表单呈现在一起,但是这些表单是而不是,它必然与特定的数据库模型相关(这不是您所需要的,因为您有所有的模型)
  • modelformset_factory允许您一起创建/编辑一组Django模型对象,例如,如果您正在管理“菜单”,则可以使用modelformset_factory(Dish, fields=('name'))
  • inlineformset_factory允许您管理与另一个模型的单个实例相关的一组Django模型对象。例如,如果您想管理在某一次特定用餐中使用的所有MealPhotos,那么您将使用以下方法

要回答您的具体情况:

如果您想要一个同时创建一顿饭和一个预订的页面,而不指定任何菜,则不需要任何格式集。您只需使用ModelForm作为晚餐,ModelForm用于预订。

稍后,如果要将多个菜肴附加到餐中,则可以使用inlineformset_factory(Meal, Dish)编辑属于一顿饭的多个菜。

由于我们使用的是一个inlineformset_factory,所以我们必须在呈现表单的视图中创建view实例。就像这样:

代码语言:javascript
复制
DishFormSet = inlineformset_factory(Meal, Dish)
bday_dinner = Meal.objects.create(name='30th Birthday dinner')
formset = DishFormSet(instance=bday_dinner)

如果有人上传了这顿饭的照片,你可以使用:

代码语言:javascript
复制
PhotosFormSet = inlineformset_factory(Meal, MealPhotos)
bday_dinner = Meal.objects.get(name='30th Birthday dinner')
formset = PhotosFormSet(instance=bday_dinner)

这告诉Django,所有提交的照片都与这一顿饭相关联,但允许将每一张照片分配给不同的Dish (通过表单中的下拉列表)。

注意:在第一个场景中,我还没有测试formset工厂是否支持使用ManyToManyField作为Meal.dishes。如果不是,那么您可以简单地使用一个ModelFormset(Dish),在创建它们之后,将它们链接到Django视图中处理表单提交的套餐。

票数 30
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53035151

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档