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

时间:2015-03-22 16:06:25

标签: python django django-forms

在我的代码中,CreateNoticeForm工作正常,所有数据都被完美保存,除了 在我的通知模型中标记的多对多字段。虽然它在管理站点上工作并被保存。

这是我的代码 的 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

形式,吡

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)

1 个答案:

答案 0 :(得分:1)

您必须致电save_m2m()

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

摘自the documentation

  

如果您的模型具有多对多关系,并且在保存表单时指定commit=False,则Django无法立即保存多对多关系的表单数据。这是因为在实例存在于数据库中之前,无法为实例保存多对多数据。

     

要解决此问题,每次使用commit=False保存表单时,Django都会向save_m2m()子类添加ModelForm方法。手动保存表单生成的实例后,可以调用save_m2m()来保存多对多表单数据。