Django - 在模板中显示多对多字段表单并提交到基础数据

0 投票
1 回答
840 浏览
提问于 2025-04-17 20:38

大家好,请帮帮我 :)
我有两个类:
第一个类可以让我们填写一些信息,比如名字、姓氏、电话和邮箱。
第二个类可以显示一个表单,里面有版本号和注册了这个版本的用户。
我想在模板中只显示“发布”的版本号。
在页面上,我们可以选择版本(下拉列表/多选),填写名字等,然后保存到这个版本中。
我知道我写得很糟糕,但希望你们能理解..

模型:

class Signup(models.Model):
    name = models.CharField(max_length=30, verbose_name='Imię',)
    surname = models.CharField(max_length=30, verbose_name='Nazwisko', blank=True, null=True)
    phone = models.CharField(max_length=20, verbose_name='Numer telefonu', blank=True, null=True)
    mail = models.EmailField(verbose_name="Email", max_length=254, blank=True, null=True)
    home = models.CharField(max_length=40, verbose_name='Miejsce zamieszkania', blank=True, null=True)
    nr_edition = models.ManyToManyField('Edition', verbose_name='Edycja', blank=True, null=True,)


class Meta:
        verbose_name = "Uczestnik"
        verbose_name_plural = "Uczestnicy"

    def __unicode__(self):
        return u'%s %s' % (self.name, self.surname)



class PublishedEditManager(models.Manager):
    def get_query_set(self):
        return super(PublishedEditManager, self).get_query_set().filter(published=True)

class Edition(models.Model):
    name_edit = models.CharField('Nazwa edycji', max_length=100)
    slug = models.SlugField('Odnośnik', unique=True, max_length=100)
    # new_user = formset_factory(ContactForm)
    published = models.BooleanField('Opublikowany', blank=True)
    objects = models.Manager()
    published_edition = PublishedEditManager()

    class Meta:
        verbose_name = "Numer edycji"
        verbose_name_plural = "Numery edycji"

    def __unicode__(self):
        return self.name_edit

    def get_absolute_url(self):
        return u'%s' % self.name_edit

表单

class ContactForm(forms.Form):
    name = forms.CharField()
    surname = forms.CharField()
    phone = forms.CharField()
    mail = forms.EmailField()
    nr_edition = forms.ModelMultipleChoiceField

    def is_valid(self):
        vf = forms.Form.is_valid(self)
        for f in self.errors:
            self.fields[f].widget.attrs.update({'class': 'errorlist'})
        return vf

    def clean(self):
        cleaned_data = super(ContactForm, self).clean()
        return cleaned_data

ContactFormSet = formset_factory(ContactForm)

视图

def about_alfa(request):
    c = {}
    c['about_alfa'] = True
    c['request'] = request

    if request.method == 'POST': # If the form has been submitted...
        form = ContactForm(request.POST, request.FILES) # A form bound to the POST data
        ContactFormSet = formset_factory(ContactForm)

        if form.is_valid(): # All validation rules pass
            name = form.cleaned_data['name']
            surname = form.cleaned_data['surname']
            phone = form.cleaned_data['phone']
            mail = form.cleaned_data['mail']
            nr_edition = form.cleaned_data['nr_edycji']

            id_model = Signup.objects.create(
                name=name,
                surname=surname,
                phone=phone,
                mail=mail,
                nr_edycji=nr_edition
            )

            c['form'] = form
            c['send']= True
            # print sendimage
            text = u'Imię: %s \n' \
                   u'Nazwisko: %s \n' \
                   u'Telefon: %s \n' \
                   u'Mail: %s \n' % (name, surname, phone, mail)

            html = u'<p>Imię: <strong>%s</strong></p>' \
                   u'<p>Nazwisko: <strong>%s</strong></p>' \
                   u'<p>Telefon: <strong>%s</strong></p>' \
                   u'<p>Mail: <strong>%s</strong></p>' % (name, surname, phone, mail)
            sendMailTemplate(['dp@asd.pl'], 'Nowa osoba zapisała się ne Alfe.', text, html, copy=False,
            )

            return render(request, 'about_alfa.html', c)
        else:
            c['form'] = form
            return render(request, 'about_alfa.html', c)
    else:
        c['form'] = ContactForm()

    return render_to_response('about_alfa.html', c, context_instance=RequestContext(request))

编辑

模型

没有变化

表单

我删除了第一部分,结果是:

class ContactForm(forms.ModelForm):
    class Meta:
        model = Signup
    nr_edition = forms.ModelMultipleChoiceField(queryset=Edition.objects.all())

    def save(self):
        signup = forms.ModelForm.save(self)
        for edition in self.cleaned_data['nr_edition']:
             signup.edition_set.add(edition)

    def clean(self):
        cleaned_data = super(ContactForm, self).clean()
        return cleaned_data

ContactFormSet = formset_factory(ContactForm)

视图

我几乎删除了所有内容,结果是:

 def about_alfa(request):
        c = {}
        c['about_alfa'] = True
        c['request'] = request
        if request.method == 'POST': # If the form has been submitted...
        form = ContactForm(request.POST, request.FILES) # A form bound to the POST data
        ContactFormSet = formset_factory(ContactForm)
           if form.is_valid():
               form.save()
        return render_to_response('about_alfa.html', c, context_instance=RequestContext(request))

编辑 2

我没有错误,但在模板中看不到任何字段(只有提交按钮^^)..?

1 个回答

0

使用 ModelFormModelMultipleChoiceField

   class ContactForm(forms.ModelForm):
        class Meta:
            model = Signup
        nr_edition = forms.ModelMultipleChoiceField(queryset=Edition.objects.all())

        def save(self):
            signup = forms.ModelForm.save(self)
            for edition in self.cleaned_data['nr_edition']:
                 signup.edition_set.add(edition)

在你的视图中,你只需要保存这个表单:

if form.is_valid():
    form.save()

在模板中:

<form action="{% url "viewname" %}" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>

补充说明:

如果要将表单集合与 ModelForm 一起使用,你必须使用 modelformset_factory查看文档,而不是 formset_factory

ContactFormSet = modelformset_factory(Signup, form=ContactForm)

另外,你在实例化 ContactForm 时,应该用 request.POST 来实例化 ContactFormSet。 所以视图的代码应该是这样的:

def about_alfa(request):
        c = {}
        c['about_alfa'] = True
        c['request'] = request
        ContactFormSet = modelformset_factory(Signup, form=ContactForm)
        if request.method == 'POST':
            formset = ContactFormSet(request.POST, request.FILES)
            if formset.is_valid():
               formset.save()
            else:
               c['form'] = formset
        else:
            c['form'] = ContactFormSet()
        return render_to_response('about_alfa.html', c, context_instance=RequestContext(request))

撰写回答