Две формы в одном представлении, когда мне нужен идентификатор первого на втором - PullRequest
0 голосов
/ 02 мая 2020

Henlo. Я создаю простое веб-приложение, в котором вы можете создавать свои собственные опросы. Это расширение к учебному приложению на сайте django. Итак, я создал вид, где вы можете увидеть свои опросы, создать опрос, войти, зарегистрироваться и т. Д. c. Проблема в том, что когда вы создаете свой опрос, у вас есть два представления. Один для создания топи c опроса и один, где вы создаете варианты, которые вы хотите иметь в опросе. Я делаю это в двух представлениях, потому что в Choice должен быть идентификатор вопроса, который создается при создании topi c опроса. Итак, вот мой вопрос, есть ли возможность сделать это на одной странице? Я попытался просто добавить две формы к одному представлению, но когда я отправил формы, ничего не произошло. Я пытался использовать некоторые из ответов, которые я нашел на Google, но я не мог найти тот, который будет работать. Проблема в том, что у Choice должен быть идентификатор вопроса в качестве внешнего ключа, и поэтому я делаю это с двух точек зрения. Но не знаю, как это сделать на одной странице. Я только начал свое приключение с django, поэтому я не совсем уверен, как это сделать.

Вот мой код.

models.py

User = auth.get_user_model()

class Question(models.Model):
    question_text = models.CharField(max_length=200)
    author = models.ForeignKey(User, on_delete=models.CASCADE, null=False)
    def __str__(self):
        return self.question_text
    def total_votes(self):
        """Calculates the total number of votes for this poll."""
        return self.choice_set.aggregate(Sum('votes'))['votes__sum']

class Choice(models.Model):
    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    choice_text = models.CharField(max_length=200)
    votes = models.IntegerField(default=0)
    def __str__(self):
        return self.choice_text
    def get_votes_perc(self):
        """Calculates the percentage of votes for this choice."""
        total = self.question.total_votes()
        return self.votes / float(total) * 100 if total > 0 else 0


class User(auth.models.User, auth.models.PermissionsMixin):

    def __str__(self):
        return "@{}".format(self.username)

class Votes_ip(models.Model):
    client_ip = models.GenericIPAddressField()
    voted_question = models.ForeignKey(Question, on_delete=models.CASCADE, null=True)

    def __str__(self):
        return self.client_ip

views.py

from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import get_object_or_404, render, redirect, render_to_response
from django.urls import reverse, reverse_lazy
from django.views import generic
from django.contrib.auth.mixins import LoginRequiredMixin
from django.forms.models import modelformset_factory
from ipware import get_client_ip
from django import forms
# from .forms import CreateChoiceForm
from.models import Question
from django.utils import timezone

from .models import Choice, Question, Votes_ip
from . import forms


# Create your views here.

class IndexView(generic.TemplateView):
    template_name = 'polls/index.html'

class ListView(generic.ListView):
    template_name = 'polls/createdPolls.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        queryset = Choice.objects.order_by('id').distinct()


class DetailView(generic.DetailView):
    model = Question
    template_name = 'polls/detail.html'

class UserDetailPollView(generic.DetailView):
    model = Question
    template_name = 'polls/UserDetailPoll.html'

class ResultsView(generic.DetailView):
    model = Question
    template_name = 'polls/results.html'



class UserPolls(LoginRequiredMixin,generic.ListView):
    template_name = 'polls/myPolls.html'
    model = Question
    context_object_name = 'user_questions_list'

    def get_queryset(self):
        return Question.objects.filter(author=self.request.user)

def vote(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    try:
        selected_choice = question.choice_set.get(pk=request.POST['choice'])
    except (KeyError, Choice.DoesNotExist):
        # Redisplay the question voting form.
        return render(request, 'polls/detail.html', {
            'question': question,
            'error_message': "You didn't select a choice.",
        })
    else:
        ip = get_client_ip(request)
        try:
            Votes_ip.objects.get(client_ip=ip, voted_question = question)
            return render(request, 'polls/detail.html', {
                'question': question,
                'error_message': "You have already voted on this poll."
            })
        except Votes_ip.DoesNotExist:  # -----Here My Edit
            ip_address = Votes_ip(client_ip=ip, voted_question = question)
            ip_address.save()
        selected_choice.votes += 1
        selected_choice.save()
        print("IP:", Votes_ip.objects.all())

        # Always return an HttpResponseRedirect after successfully dealing
        # with POST data. This prevents data from being posted twice if a
        # user hits the Back button.
        return HttpResponseRedirect(reverse('pollapp:results', args=(question.id,)))

class SignUp(generic.CreateView):
    form_class = forms.UserCreateForm
    success_url = reverse_lazy('login')
    template_name = 'registration/signup.html'

class CreatePoll(LoginRequiredMixin, generic.CreateView):
    form_class = forms.CreatePollForm
    template_name = 'polls/createPoll.html'


    def form_valid(self, form):
        self.object = poll = form.save(commit=False)
        poll.author = self.request.user
        poll.save()
        return super().form_valid(form)

    def get_success_url(self):
        return reverse('pollapp:createChoice', kwargs={ "pk": self.object.pk })

def createChoice(request, pk):
    question = get_object_or_404(Question, pk=pk)
    ChoiceFormSet = modelformset_factory(Choice, form=forms.CreateChoiceForm,)
    if request.method == 'POST':
        formset = ChoiceFormSet(request.POST, queryset=Choice.objects.filter(question__id=question.id))
        if formset.is_valid():
            instances = formset.save(commit=False)
            for instance in instances:
                instance.question_id = question.id
                instance.save()
            return HttpResponseRedirect(reverse('pollapp:results', args=(question.id,)))
    else:
        formset = ChoiceFormSet(queryset=Choice.objects.filter(question__id=question.id))

    print ("Questions:", (Choice.objects.all()))
    return render(request, 'polls/createChoice.html', {'formset': formset})

forms.py

from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm
from django import forms
from .models import Question, Choice, User
from django.forms.models import modelformset_factory


class UserCreateForm(UserCreationForm):

    class Meta:
        fields = ('username', 'email', 'password1', 'password2')
        model = get_user_model()

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['username'].label = 'Display Name'
        self.fields['email'].label = 'Email Address'
    def clean_username(self):
        username = self.cleaned_data['username']
        if User.objects.exclude(pk=self.instance.pk).filter(username=username).exists():
            raise forms.ValidationError('Username is already in use')
        return username

class CreatePollForm(forms.ModelForm):

    class Meta:
        model = Question
        fields = ('question_text',)
class CreateChoiceForm(forms.ModelForm):
    class Meta:
        model = Choice
        fields = ['choice_text',]
        widgets = {
            'choice_text': forms.TextInput(attrs={ 'class': 'form-control'}),
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...