Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python DjangoAdmin表单与1:N选择无法保存对象_Python_Django_Django Forms_Django Rest Framework_Django Admin - Fatal编程技术网

Python DjangoAdmin表单与1:N选择无法保存对象

Python DjangoAdmin表单与1:N选择无法保存对象,python,django,django-forms,django-rest-framework,django-admin,Python,Django,Django Forms,Django Rest Framework,Django Admin,我正在寻找一种方法,将一个或多个已经存在的对象指定给当前对象,同时在“添加”部分中创建。类似内联,但我不想创建它们,只选择并分配 两个示例模型: class Location(models.Model): name = models.CharField(max_length=30) class Device(models.Model): name = models.CharField(max_length=20) location = models.ForeignKey

我正在寻找一种方法,将一个或多个已经存在的对象指定给当前对象,同时在“添加”部分中创建。类似内联,但我不想创建它们,只选择并分配

两个示例模型:

class Location(models.Model):
    name = models.CharField(max_length=30)

class Device(models.Model):
    name = models.CharField(max_length=20)
    location = models.ForeignKey(Location, null=True, blank=True, on_delete=models.DO_NOTHING)
因此,在Django Admin中创建
位置时,我希望能够分配1-N个现有
设备

我找到了一种方法,使用一个定制的
表单

这是我在
admin.py中的自定义表单

class LocationForm(forms.ModelForm):
    class Meta:
        model = Location
        fields = '__all__'

    devices = forms.ModelMultipleChoiceField(queryset=Device.objects.all()) 

    def __init__(self, *args, **kwargs):
        super(LocationForm, self).__init__(*args, **kwargs)
        if self.instance:
            self.fields['devices'].initial = self.instance.device_set.all()

    def save(self, *args, **kwargs):
        instance = super(LocationForm, self).save(commit=False)
        self.fields['devices'].initial.update(location=None)
        self.cleaned_data['devices'].update(location=instance)
        return instance

@admin.register(Location)
class LocationAdmin(admin.ModelAdmin):
    form = LocationForm
只要我不保存
位置
对象,就可以了。下面是一张它在django admin中的外观图片。

但是,当我尝试保存位置时,出现以下错误:

 File "admin.py", line 21, in save
    api          |     self.cleaned_data['devices'].update(location=instance)
    api          |   File "/usr/local/lib/python3.6/site-packages/django/db/models/query.py", line 692, in update
    api          |     rows = query.get_compiler(self.db).execute_sql(CURSOR)
    api          |   File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1378, in execute_sql
    api          |     cursor = super().execute_sql(result_type)
    api          |   File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1054, in execute_sql
    api          |     sql, params = self.as_sql()
    api          |   File "/usr/local/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1334, in as_sql
    api          |     val.prepare_database_save(field),
    api          |   File "/usr/local/lib/python3.6/site-packages/django/db/models/base.py", line 932, in prepare_database_save
    api          |     raise ValueError("Unsaved model instance %r cannot be used in an ORM query." % self)
    api          | ValueError: Unsaved model instance <Location: Test Project> cannot be used in an ORM query.
文件“admin.py”,第21行,保存
api | self.cleaned_数据['devices'].update(位置=实例)
api |文件“/usr/local/lib/python3.6/site packages/django/db/models/query.py”,第692行,更新中
api | rows=query.get_编译器(self.db).执行_sql(游标)
api |文件“/usr/local/lib/python3.6/site packages/django/db/models/sql/compiler.py”,第1378行,在执行sql中
api | cursor=super()。执行sql(结果类型)
api |文件“/usr/local/lib/python3.6/site packages/django/db/models/sql/compiler.py”,执行sql中的第1054行
api | sql,params=self.as_sql()
api |文件“/usr/local/lib/python3.6/site packages/django/db/models/sql/compiler.py”,as|sql中的第1334行
api | val.prepare_database_save(字段),
api |文件“/usr/local/lib/python3.6/site packages/django/db/models/base.py”,第932行,在prepare_database_save中
api | raise VALUERROR(“未保存的模型实例%r不能用于ORM查询。”%self)
api | ValueError:无法在ORM查询中使用未保存的模型实例。

我尝试过在save方法中手动保存对象,但也没有成功,我已经没有办法了,因为我真的不知道为什么它根本不保存。我认为从超类中使用save方法就足够了,但显然不是这样。

在阅读了我的问题大约七次之后,才找到它

日志的第一行写着
self.cleaned_data['devices'].update(location=instance)
,显然
实例是未保存的,因此不能用作查询参数,所以我像这样编辑了表单的保存方法

def save(self, *args, **kwargs):
        instance = super(LocationForm, self).save(commit=False)
        self.fields['devices'].initial.update(location=None)
        instance.save()
        self.cleaned_data['devices'].update(location=instance)        
        return instance
它正在发挥作用