django 中的多对多字段在管理站点中工作,但不在前端站点表单中工作

many to many field in django is working in admin site but not in front end site form

在我的代码中,CreateNoticeForm 工作正常,所有数据都得到完美保存,除了 多对多字段,这是我注意到的标签 model.Although 它正在管理站点上工作并被保存。

这是我的代码 models.py

from django.db import models
from django.contrib.auth.models import User

from wysihtml5.fields import Wysihtml5TextField

# Create your models here.
class Tag(models.Model):
    # For notice tags
    name = models.CharField(max_length=70, unique=True)

    def __str__(self):
        return self.name


class Notice(models.Model):
    # Notice Store
    headline = models.CharField(max_length=140)
    description = Wysihtml5TextField()
    file_name = models.FileField(upload_to='static/noticefiles/', blank=True)
    created_by = models.ForeignKey(User)
    fors = models.CharField(max_length=1, choices=(('F','Faculty'),('S','Student'),) )
    last_date = models.DateField()
    tags = models.ManyToManyField(Tag, blank=True)
    post_time = models.DateTimeField(auto_now_add=True)
    update_time = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.headline

表格,py

FORS_CHOICES = (('F','Faculty'),('S','Student'))


class CreateNoticeForm(ModelForm):
    fors = forms.ChoiceField(label="Related To",
                             choices=FORS_CHOICES,
                            )
    class Meta:
        model = Notice
        fields = ('headline', 'description',
                  'fors', 'last_date', 'tags','file_name')
        widgets = {
            'description': Wysihtml5BootstrapWidget(),
            'last_date': SelectDateWidget()
        }
    def __init__(self, *args, **kwargs):
        super(CreateNoticeForm, self).__init__(*args, **kwargs)
        self.helper = FormHelper()
        self.helper.form_id = 'create_notice_form_id'
        self.helper.form_class = 'form-horizontal'
        self.helper.form_method = 'post'
        self.helper.label_class = 'col-lg-2'
        self.helper.field_class = 'col-lg-8'
        self.helper.layout = Layout(
            Fieldset('Create Notice',
                     'headline', 
                     'description',
                     Field('fors', label='Audience'),
                     MultiWidgetField('last_date',
                        attrs=(
                            {'style': 'width: 33.33%; display: inline-block;'}
                        )
                     ),
                     'tags',
                     'file_name',
                     FormActions(
                        Submit('save', 'Create Notice', 
                        css_class='btn-warning col-lg-offset-2'),
                     ),
            ),

views.py

def create_notice(request):

    context = RequestContext(request)

    posted = False

    if request.method=='POST':
        create_notice_form = CreateNoticeForm(data=request.POST, files=request.FILES)

        if create_notice_form.is_valid():
            cnf = create_notice_form.save(commit=False)
            cnf.created_by = request.user
            cnf.save()
            posted = True
        else:
            print(create_notice_form.errors)

    else:
        create_notice_form = CreateNoticeForm()


    return render_to_response('notices/createnotice1.html',
                              {'create_notice_form': create_notice_form,
                               'posted': posted,},
                              context)

您必须致电 save_m2m():

cnf = create_notice_form.save(commit=False)
cnf.created_by = request.user
cnf.save()
create_notice_form.save_m2m()

摘自the documentation

If your model has a many-to-many relation and you specify commit=False when you save a form, Django cannot immediately save the form data for the many-to-many relation. This is because it isn’t possible to save many-to-many data for an instance until the instance exists in the database.

To work around this problem, every time you save a form using commit=False, Django adds a save_m2m() method to your ModelForm subclass. After you’ve manually saved the instance produced by the form, you can invoke save_m2m() to save the many-to-many form data.