django模型选择选项作为多选框

Hel*_*nar 10 python django django-models

假设我有这样的模特

COLORS= (
    ('R', 'Red'),
    ('B', 'Yellow'),
    ('G', 'White'),
)
class Car(models.Model):
    name = models.CharField(max_length=20)
    color= models.CharField(max_length=1, choices=COLORS)
Run Code Online (Sandbox Code Playgroud)

它在管理面板中显示为选择框但是我希望我的管理员用户多选择那些颜色,如多对多关系,如何在没有一种('RB', 'Red&Blue'),逻辑的情况下实现这一点

Man*_*dan 11

可以Car有多个colors吗?在这种情况下,color应该是多对多的关系,而不是一个CharField.另一方面,如果您想要执行类似Unix权限(即Red + Blue,Red + Blue + Green等)的操作,则为每个权限分配数值并创建color一个整数字段.

更新

(阅读评论后)您可以使用自定义表单在Admin中编辑模型,而不是默认模式ModelForm.此自定义表单可以使用多选小部件,用户可以选择多种颜色.然后,您可以覆盖clean()表单的方法以返回适当连接的值('RB'等).

更新2

这是一些代码:

首先,从模型字段中删除选项.同时将其最大尺寸增加到2.我们不想在这里做出选择 - 如果我们这样做,那么我们将不得不为每种颜色组合添加一个选择.

class Car(models.Model):
    ...
    color= models.CharField(max_length=2)
Run Code Online (Sandbox Code Playgroud)

第二步添加自定义ModelForm以在管理员应用中使用.此表单将覆盖颜色,而是将其声明为多选字段.我们确实需要这里的选择.

COLORS= (
    ('R', 'Red'),
    ('B', 'Yellow'),
    ('G', 'White'),
)

class CarAdminForm(ModelForm):
    color = forms.MultipleChoiceField(choices = COLORS)

    class Meta:
        model = Car

    def clean_color(self):
        color = self.cleaned_data['color']
        if not color:
            raise forms.ValidationError("...")

        if len(color) > 2:
            raise forms.ValidationError("...")

        color = ''.join(color)
        return color
Run Code Online (Sandbox Code Playgroud)

请注意,我只添加了几个验证.您可能需要更多和/或自定义验证.

最后,使用admin注册此表单.你的内心admin.py:

class CarAdmin(admin.ModelAdmin):
    form = CarAdminForm

admin.site.register(Car, CarAdmin)
Run Code Online (Sandbox Code Playgroud)


Ser*_*jik 6

我已经用有意义的模型构建了一个完整的工作示例。它完美无缺。我已经在 Python 3.4.x 和 Django 1.8.4 上测试过它。首先我运行管理面板并为 Thema 模型中的每个选项创建记录

模型.py

from django.db import models

class Author(models.Model):
    fname = models.CharField(max_length=50)
    lname = models.CharField(max_length=80)

    def __str__(self):
        return "{0} {1}".format(self.fname, self.lname)


class Thema(models.Model):
    THEME_CHOICES = (
        ('tech', 'Technical'),
        ('novel', 'Novel'),
        ('physco', 'Phsycological'),
    )
    name = models.CharField(max_length=20,choices=THEME_CHOICES, unique=True)

    def __str__(self):
        return self.name

class Book(models.Model):

    name = models.CharField(max_length=50)
    author = models.ForeignKey(Author)
    themes = models.ManyToManyField(Thema)

    def __str__(self):
        return "{0} by {1}".format(self.name,self.author)
Run Code Online (Sandbox Code Playgroud)

表格.py

from django import forms

from .models import *

class BookForm(forms.ModelForm):
    themes = forms.ModelMultipleChoiceField(queryset=Thema.objects, widget=forms.CheckboxSelectMultiple(), required=False)
Run Code Online (Sandbox Code Playgroud)

管理文件

from django.contrib import admin

from .models import *
from .forms import *

@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
    pass


@admin.register(Book)    
class BookAdmin(admin.ModelAdmin):
    form = BookForm


@admin.register(Thema)
class ThemaAdmin(admin.ModelAdmin):
    pass
Run Code Online (Sandbox Code Playgroud)