在Django管理界面中,无法保存多个实例到一个表单中。

huangapple go评论69阅读模式
英文:

failed to saving multiple instance in one form in django admin

问题

我是你的中文翻译助手,以下是翻译好的内容:

我刚接触Django,正在尝试创建一个帐户表单,其中你可以选择一个用户并勾选你想要的平台,然后它会在帐户表中为该用户创建一个帐户,并将每个勾选的平台与之关联。

所以:
我有三个模型:users(用户)、platforms(平台)和accounts(帐户),它们在model.py文件中定义如下:

class User(models.Model):
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

class Platform(models.Model):
    platform_name = models.CharField(max_length=255)
    platform_link = models.CharField(max_length=255)

class Account(models.Model):
    platform = models.ForeignKey(Platform, on_delete=models.PROTECT)
    user = models.ForeignKey(User, on_delete=models.PROTECT)

然后我创建了一个AccountForm类:

class AccountForm(ModelForm):
    platforms = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(), queryset=Platform.objects.all())

    class Meta:
        model = Account
        fields = ["user", "platforms"]
        widgets = {'platform': forms.HiddenInput()}

在admin.py中:

class AccountAdmin(admin.ModelAdmin):
    list_display = ["id", "platform", "user"]
    form = AccountForm

    def save_form(self, request, form, change):
        platforms = form.cleaned_data["platforms"]
        if platforms:
            accounts_to_save = []
            for platform in platforms:
                account = form.save(commit=False)
                form.instance.platform = platform
                accounts_to_save.append(account)

            Account.objects.bulk_create(accounts_to_save)
        else:
            return super().save_form(request, form, change)
        return super().save_form(request, form, change)

我尝试遍历选中的平台并保存每个实例,但它始终保存具有平台列表中最后一个值的实例。所以,如果我们选择用户2并勾选平台1和平台2,它会保存[(用户2,平台2),(用户2,平台2)],而不是[(用户2,平台1),(用户2,平台2)]。

英文:

I am new to Django and I am trying to create an account form where you select a user and check the platforms you want and it creates an account in the account table for the user with each platform checked.
so :
I have three models: users, platforms, and accounts in the model.py file

class User(models.Model):
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

class Platform(models.Model):
    platform_name = models.CharField(max_length=255)
    platform_link = models.CharField(max_length=255)

class Account(models.Model):
    platform = models.ForeignKey(Platform, on_delete=models.PROTECT)
    user = models.ForeignKey(User, on_delete=models.PROTECT)

I then created an AccountForm class

class AccountForm(ModelForm):
    platforms = forms.ModelMultipleChoiceField(widget=forms.CheckboxSelectMultiple(), queryset=Platform.objects.all())

    class Meta:
        model: Account
        fields = ["user", "platforms"]
        widgets = {'platform': forms.HiddenInput()}

in the admin.py

class AccountAdmin(admin.ModelAdmin):
    list_display =  ["id", "platform", "user"]
    form = AccountForm
  
    
    def save_form(self, request: Any, form: Any, change: Any) -> Any:  
        platforms = form.cleaned_data["platforms"]
        if platforms:
            accounts_to_save = []
            for platform in platforms:
                account = form.save(commit=False)
                form.instance.platform = platform
                accounts_to_save.append(account)
            
            Account.objects.bulk_create(accounts_to_save)
        else:
            return super().save_form(request, form, change)
        return super().save_form(request, form, change)
    

I tried iterating through the checked platforms and saving each time, but it keeps saving the instances with only the last value of in the platforms list. so if we select user 2 and checked platform 1 and platform 2 >> it saves [(user 2, platform 2) ,(user 2, platform 2) ] instead of [(user 2, platform 1) ,(user 2, platform 2) ]

答案1

得分: 0

问题是在最后一个返回的super.save_form中发送的表单必须填写。

我最终通过迭代我的平台并使用objects.create创建账户,将最后一个账户留给在表单中发送的账户,以便super方法中发送的表单不为空。

def save_form(self, request: Any, form: Any, change: Any) -> Any:  
    platforms = form.cleaned_data['platforms']
    if platforms:
        for p in platforms[:len(platforms)-1]:
            Account.objects.create(platform=p, user=form.cleaned_data['user'])
        form.instance.platform = platforms[len(platforms)-1]
    return super().save_form(request, form, change)
英文:

The problem was that the form sent in the last return super.save_form must be filled.

I ended up iterating through my platforms and creating the accounts with objects.create, and left the last one to be the one sent in the form so that the form sent in the super method isn't empty.

def save_form(self, request: Any, form: Any, change: Any) -> Any:  
    platforms = form.cleaned_data['platforms']
    if platforms:
        for p in platforms[:len(platforms)-1]:
            Account.objects.create( platform= p ,user=form.cleaned_data['user'])
        form.instance.platform = platforms[len(platforms)-1]
    return super().save_form(request, form, change)

</details>



huangapple
  • 本文由 发表于 2023年8月8日 22:05:37
  • 转载请务必保留本文链接:https://go.coder-hub.com/76860335.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定