Linking instance of a model with instance of a different model using ModelForm

General Tech Bugs & Fixes 2 years ago

0 2 0 0 0 tuteeHUB earn credit +10 pts

5 Star Rating 1 Rating

Posted on 16 Aug 2022, this text provides information on Bugs & Fixes related to General Tech. Please note that while accuracy is prioritized, the data presented might not be entirely correct or up-to-date. This information is offered for general knowledge and informational purposes only, and should not be considered as a substitute for professional advice.

Take Quiz To Earn Credits!

Turn Your Knowledge into Earnings.

tuteehub_quiz

Answers (2)

Post Answer
profilepic.png
manpreet Tuteehub forum best answer Best Answer 2 years ago

 

I have two models, "Fixture" and "PlayerVotes". The PlayerVotes model has two foreign keys, a link to a particular fixture and the voter (request.user).

I want to display the entire list of fixture as an expandable accordion (bootstrap4) and allow the logged in user to give some votes for each instance of fixture. I am not sure where I could have the form validation and the save() functions.

models.py

class Fixture(models.Model):
    season = models.PositiveIntegerField(blank=False, null=False,
            validators=[
                MinValueValidator(2019),
                MaxValueValidator(datetime.now().year)])
    round = models.PositiveIntegerField(blank=False, null=False)
    game_time = models.DateTimeField(blank=True, null=True)
    opponent = models.ForeignKey(Teams, on_delete=models.SET_NULL, null=True)
    goals_for = models.PositiveIntegerField(null=True)
    goals_againt = models.PositiveIntegerField(null=True)

    def __str__(self):
        return 'Round '+str(self.round)+ ' ('+str(self.season)+ ')'

class PlayerVotes(models.Model):
    voter = models.ForeignKey(User,related_name="voter" ,on_delete=models.SET_NULL, null=True)
    round = models.ForeignKey(Fixture, on_delete=models.SET_NULL, null=True)
    three_votes = models.ForeignKey(User,related_name="three_votes" ,on_delete=models.SET_NULL, null=True)
    two_votes = models.ForeignKey(User,related_name="two_votes" ,on_delete=models.SET_NULL, null=True)
    one_vote = models.ForeignKey(User,related_name="one_vote", on_delete=models
                                                
                                                
0 views
0 shares
profilepic.png
manpreet 2 years ago

 

Form validation is done when you submit form using post request. The code you are showing is for rendering forms, you need a different view to handle the form submissions. You can do it like this:

Modify Form __init__

 def __init__(self, *args, **kwargs):
    self.voter = kwargs.pop('user', None)
    self.round = kwargs.pop('round', None)
    super(PlayerVotesForm, self).__init__(*args, **kwargs)

Modify your current View:

# inside your votes view
for game in fixtures:
    games[game] = forms.PlayerVotesForm(user=request.user, round=game)
return render(request, 'votes/display.html', context={'games':games})

Template

{% for game, form in games.items %}
    <h1> {{ game.round }} h1>
    ...
    <form action="{% url 'cast-vote' game.pk %}" method="post">
         {{ form.as_p }}
         <input type="submit" value="OK">
    form>

{% enfor %}

Now you need to handle the form submission given above:

View

def cast_vote(request, pk):
     game = get_object_or_404(Game, pk=pk)
     if request.method == "POST":
        form = PlayerVotesForm(request.POST, user=request.user, round=game)
        if form.is_valid():
            # do other logics
     return redirect('votes-url')

Url

  path('castvote//', cast_vote, name="cast-vote")

0 views   0 shares

No matter what stage you're at in your education or career, TuteeHub will help you reach the next level that you're aiming for. Simply,Choose a subject/topic and get started in self-paced practice sessions to improve your knowledge and scores.