具有两个外键的表的Inlineformset_factory

时间:2018-05-24 14:56:46

标签: python django foreign-keys models formsets

我正在尝试扩展使用构建投票应用的官方django教程。目前,我尝试做的是允许用户创建民意调查,输入民意调查名称,民意调查选项,并通过已注册用户的电子邮件邀请他想要的用户。

我的model.py

class Poll(models.Model):
    question_text = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published', auto_now_add=True)
    is_active = models.BooleanField(default=True)
    activation_date = models.DateTimeField('Activation Date', blank=True, null=True)
    expiration_date = models.DateTimeField('Expiration Date', blank=True, null=True)
    public_key = models.CharField(max_length=30, blank=True)
    hash = models.CharField(max_length=128, blank=True)
    timestamp = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.question_text

    def was_published_recently(self):
        now = timezone.now()
        return now - datetime.timedelta(days=1) <= self.pub_date <= now
    was_published_recently.admin_order_field = 'pub_date'
    was_published_recently.boolean = True
    was_published_recently.short_description = 'Published recently?'


class Choice(models.Model):
    question = models.ForeignKey(Poll, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)

    def __str__(self):
        return self.choice_text


class EligibleVoters(models.Model):
    user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
    poll = models.ForeignKey(Poll, on_delete=models.CASCADE)
    email = models.EmailField(null=True)

我的forms.py

from django.forms import ModelForm, inlineformset_factory
from django import forms
from .models import Poll, Choice, EligibleVoters, PollKeyPart, User


class PollForm(ModelForm):
    activation_date = forms.DateTimeField(required=False)
    expiration_date = forms.DateTimeField(required=False)
    class Meta:
        model = Poll
        fields = ['question_text', 'is_active', 'activation_date', 'expiration_date']


class ChoiceForm(ModelForm):
    class Meta:
        model = Choice
        exclude = ()


ChoiceFormSet = inlineformset_factory(Poll, Choice, form=ChoiceForm, extra=1)


class EligibleVotersForm(ModelForm):
    class Meta:
        model = EligibleVoters
        fields = ['email']


EligibleVotersFormSetPoll = inlineformset_factory(Poll, EligibleVoters, form=EligibleVotersForm, extra=1)
#EligibleVotersFormSetUser = inlineformset_factory(User, EligibleVoters, form=EligibleVotersForm, extra=1)

我的views.py

class NewPoll(CreateView):
    model = Poll
    fields = ['question_text', 'is_active', 'activation_date', 'expiration_date']
    success_url = reverse_lazy('voting:index')

    def get_context_data(self, **kwargs):
        data = super(NewPoll, self).get_context_data(**kwargs)
        if self.request.POST:
            data['choices'] = ChoiceFormSet(self.request.POST)
            data['eligible_voters_poll'] = EligibleVotersFormSetPoll(self.request.POST)                
        else:
            data['choices'] = ChoiceFormSet()
            data['eligible_voters_poll'] = EligibleVotersFormSetPoll()               
        return data

    def form_valid(self, form):
        context = self.get_context_data()
        choices = context['choices']
        eligible_voters_poll = context['eligible_voters_poll']          
        with transaction.atomic():
            self.object = form.save()
            if choices.is_valid():
                choices.instance = self.object
                choices.save()
            if eligible_voters_poll.is_valid():
                eligible_voters_poll.instance = self.object
                eligible_voters_poll.save()
        return super(NewPoll, self).form_valid(form)

我的html文件:

{% extends 'base.html' %}

{% block content %}
{% load static %}
  <h2>Poll Creation</h2>
<div class="col-md-4">
  <form action='' method="post">
    {% csrf_token %}
    {{ form.as_p }}

    <table class="table">
        {{ choices.management_form }}

        {% for form in choices.forms %}
            {% if forloop.first %}
                <thead>
                <tr>
                    {% for field in form.visible_fields %}
                        <th>{{ field.label|capfirst }}</th>
                    {% endfor %}
                </tr>
                </thead>
            {% endif %}
            <tr class="{% cycle row1 row2 %} formset_row1">
                {% for field in form.visible_fields %}
                    <td>
                        {% if forloop.first %}
                            {% for hidden in form.hidden_fields %}
                                {{ hidden }}
                            {% endfor %}
                        {% endif %}
                        {{ field.errors.as_ul }}
                        {{ field }}
                    </td>
                {% endfor %}
            </tr>
        {% endfor %}
    </table>
    <table class="table">
        {{ eligible_voters_poll.management_form }}

        {% for form in eligible_voters_poll.forms %}
            {% if forloop.first %}
                <thead>
                <tr>
                    {% for field in form.visible_fields %}
                        <th>{{ field.label|capfirst }}</th>
                    {% endfor %}
                </tr>
                </thead>
            {% endif %}
            <tr class="{% cycle row1 row2 %} formset_row2">
                {% for field in form.visible_fields %}
                    <td>
                        {% if forloop.first %}
                            {% for hidden in form.hidden_fields %}
                                {{ hidden }}
                            {% endfor %}
                        {% endif %}
                        {{ field.errors.as_ul }}
                        {{ field }}
                    </td>
                {% endfor %}
            </tr>
        {% endfor %}
    </table>
    <input type="submit" value="Save"/> <a href="{% url 'voting:index' %}">back to the list</a>
    </form>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="{% static 'voting/js/jquery.formset.js' %}"></script>
<script type="text/javascript">
        $('.formset_row1').formset({
            addText: 'add poll choice',
            deleteText: 'remove',
            prefix: 'Choice_set'
        });
        $('.formset_row2').formset({
            addText: 'add eligible voter',
            deleteText: 'remove',
            prefix: 'EligibleVoters_set'
        });
</script>
{% endblock %}

目前的代码可以使用,但在我的EligibleVoters模型上,user_id列仍然为空,每个条目只会占用poll_idemail字段。不知何故,我需要将每个条目与相应的user_id相关联。最好的方法是什么?

我还想添加一个验证,你只能邀请注册用户并使用我已有的加密库为民意调查创建一个密钥对,但我也不确定如何做到这一点。

0 个答案:

没有答案