0

学校のプロジェクトの Django チュートリアルを拡張して、より使いやすい投票アプリにしようとしています。

私が望むのは、ユーザーが投票を作成し、他の登録ユーザーを電子メールで招待して投票に投票できるようにすることです。招待されたユーザーのみが投票できます。

私のmodels.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)

Poll投票のタイトルと投票に関するその他の情報を含むテーブルがあります。Choicesまた、(チュートリアルのように)別のテーブルを作成しました。このテーブルにはForeignKeyPollテーブルへのアクセスがあり、投票の選択肢が含まれています。ユーザーを適格な有権者として招待するForeignKeysには、PollおよびUserテーブルに加えて 3 つ目のテーブルが必要であると考えました。だから私はそれを作成しました。

組み込みのユーザー モデルを使用していることに注意してください。

これが私のもの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().get_context_data(**kwargs)
        if self.request.POST:
            data['choices'] = ChoiceFormSet(self.request.POST)
            # data['eligible_voters_poll'] = EligibleVotersFormSetPoll(self.request.POST)
            # data['eligible_voters_user'] = EligibleVotersFormSetUser(self.request.POST)
            #data['eligible_voters'] = EligibleVotersFormSet(self.request.POST)
        else:
            data['choices'] = ChoiceFormSet()
        #     data['eligible_voters_poll'] = EligibleVotersFormSetPoll()
        #     data['eligible_voters_user'] = EligibleVotersFormSetUser()
        #    data['eligible_voters'] = EligibleVotersFormSet()
        return data

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

私はそれを機能させるための以前の試みである行にコメントしました。コメント行がなくても、ユーザーは投票を作成したり、選択肢を作成したりできます。ただし、招待部分を機能させるのに問題があります。

これが私のものforms.pyです:

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 = ['votes']


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


def form_maker(parent2):
    class EligibleVotersForm(ModelForm):
        # def __init__(self, user, poll, *args, **kwargs):
        #     self.user = user
        #     self.poll = poll
        #     super().__init__(*args, **kwargs)

        def save(self, commit=True):
            instance = super(EligibleVotersForm, self).save(commit=False)
            # instance.parent1 = parent1
            instance.parent2 = parent2
            if commit:
                instance.save()
            return instance

        class Meta:
            model = EligibleVoters
            fields = ['email']
    return EligibleVotersForm


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

ここで、失敗した試みに属する行を再度コメントアウトしました。私がそれを機能させることに近づいたのは、(私が望む登録されたものだけでなく)任意の電子メールで招待EligibleVotersし、poll_id. しかしuser_id、列は空のままでした。

これが私の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.management_form }}

        {% for form in eligible_voters.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モデルがどういうわけか間違っていて、ManyToManyどこかにフィールドが必要なのだろうか??と考えていました。

4

0 に答える 0