首页 > 解决方案 > 使用 Textarea 覆盖 MultipleSelectField 以在 Django ModelForm 中添加许多字段

问题描述

我希望有可能使用 textarea 而不是 MultiSelect 字段添加 ManyToMany 字段。此文本区域将在 DB 中搜索标签出现或添加新标签。这是我的代码: MyModel.py

class Event(models.Model):
    name = models.CharField('Name', max_length=100, blank=True, default='')
    created_at = models.DateTimeField('Date', auto_now_add=True)
    tag = models.ManyToManyField('Tag')

class Tag(models.Model):
    value = models.CharField('Tag Value', max_length=100)

    STATE = (
        ('1', 'domain'),
        ('2', 'ip'),
        ('3', 'url'),
    )

    type = models.CharField('Type', max_length=2, choices=STATE)

管理员.py

from django.contrib import admin
from .models import Event, Tag
from . import forms

@admin.register(Event)
class EventAdmin(admin.ModelAdmin):
    list_display = ('id', 'name', 'created_at')
    form = forms.EventAdminForm

@admin.register(Tag)
class TagAdmin(admin.ModelAdmin):
    list_display = ('value', 'type')

表格.py

class EventAdminForm(forms.ModelForm):
    extra_field = forms.CharField(widget=forms.Textarea) # textarea I wish to use to dinamically add tag
    class Meta:
        model = Event
        fields = ['id', 'name', 'tag']

    def save(self, commit=True):
        event_item = super(EventAdminForm, self).save(commit=True)

        uploaded_tags = self.cleaned_data['extra_field']
        uploaded_tags = uploaded_tags.splitlines()

        event_item.tag.clear()

        tag2insert = []

        for custom_tag in uploaded_tags:
            tag_type = getTagType(custom_tag)   # ('1', 'domain') => '1'

            if tag_type != 0:
                t, created = Tag.objects.get_or_create(value=custom_tag, type=tag_type)
                tag2insert.append(i)
                # does not works
                event_item.tag.add(t)
                # does not works
                # event_item.save_m2m()

        # does not works
        # for saved_tag in tag2insert:
        #   event_item.tag.add(saved_tag)

        event_item.save()
        return event_item

我更喜欢将所有“保存”逻辑放在 forms.py 中以分隔代码。

更新:使用此代码,我有以下错误:

“EventForm”对象没有属性“save_m2m”

标签: djangodjango-forms

解决方案


在 admin.py 中覆盖save_model一切正常:

管理员.py

def save_model(self, request, obj, form, change):
    uploaded_tags  = form.cleaned_data['extra_field'].splitlines()

    obj.save()

    tag2insert = []
    for custom_tag in uploaded_tags:
        tag_type = getTagType(custom_tag)   # ('1', 'domain') => '1'

        if tag_type != 0:
            i, created = Tag.objects.get_or_create(value=custom_tag, type=tag_type)
            tag2insert.append(i)

    if len(tag2insert) > 0:
        obj.tag.set(tag2insert)

    obj.save()

现在,我的问题是:有没有办法覆盖EventAdminForm (forms.py) 中的保存方法,而不是将代码 (save_model 代码) 放在 admin.py 中?


推荐阅读