用Textarea覆盖MultipleSelectField以在Django ModelForm中添加许多字段

时间:2018-09-10 14:57:52

标签: django django-forms

我希望可以使用textarea而不是MultiSelect字段来添加ManyToMany字段。该文本区域将在数据库中搜索标签出现次数或添加新标签。 这是我的代码: 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)

admin.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')

forms.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

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

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

  

'EventForm'对象没有属性'save_m2m'

1 个答案:

答案 0 :(得分:0)

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

admin.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 方法,而不是在admin.py中放置代码(save_model代码)?