在django中设置ManyToMany字段默认值的正确方法

bis0qfac  于 2023-06-25  发布在  Go
关注(0)|答案(4)|浏览(213)

如何正确设置many2many字段的默认值?这就是我在下面尝试的,但它不起作用。我知道我可以重写保存方法,但是每次模型更新的时候不是都会调用它吗?我希望每次创建示例时只设置模型的初始值。

def default_values():
     return [c.id for c in SomeOtherModel.objects.filter(otherfield__isnull = True)]

class SomeModel(models.Model):
    somefield = models.ManyToManyField('SomeField', default=default_values)
    semeotherfield = models.ForeignKey('SomeOtherField')

我用的是Django 1.8

nfs0ujit

nfs0ujit1#

问题中提到的方法不起作用,因为ManyToManyField在保存时不能有值(值必须与RelatedManager一起添加)。因此,保存对象时(调用<object>.save()或其他时),不使用ManyToManyFielddefault选项:即使它被设置(例如,返回一个对象列表的可调用对象),保存时该字段将被设置为一个空列表。
根据this ticket
default选项值用于Django Form设置来编辑此对象。特别是,在Django Admin中,多值下拉列表将包含字段,该字段将包含定义为默认值的可调用对象返回的所有对象-并且它们都将被选中。如果用户保存对象而不进行任何编辑(通过按下表单的“保存”按钮),则该字段确实将被设置为所有值。

exdqitrt

exdqitrt2#

您可以覆盖保存方法,并在其中插入一个检查主键是否为空。如果它是空的-这是创建对象。
你也可以连接到后保存信号-有属性告诉你,如果这是创建的对象或没有。

igsr9ssn

igsr9ssn3#

你可以覆盖模型的init方法,但这不允许你设置m2m。
你可以覆盖modelform的init,如下所示:

def __init__(self, *args, **kwargs):
    if 'initial' not in kwargs:
        kwargs['initial'] = {}
    kwargs['initial'].update(product_template_admin_initial_values())
    super(ProductTemplateAdminForm, self).__init__(*args, **kwargs)

但这将不允许使用请求。
如果您依赖于请求,则可以使用admin get_changeform_initial_data

def get_changeform_initial_data(self, request):
    return {'name': 'custom_initial_value'}

你可以用请求作为参数调用一个方法,并返回一个字典。m2m默认值应该是列表

qojgxg4l

qojgxg4l4#

如果你只是想在管理页面中为M2M列表设置一个默认值,你可以这样做。例如,要将managed_by的默认值设置为当前用户:

class EventAdmin(admin.ModelAdmin):
    def get_changeform_initial_data(self, request: HttpRequest):
        defaults = super().get_changeform_initial_data(request)
        defaults['managed_by'] = [request.user]
        return defaults

这里我们也调用super().get_changeform_initial_data,这样我们就不会失去Django设置的默认值。

相关问题