Home > Django > djangofantalega: model Trade

djangofantalega: model Trade

10 – Models: Trade

Le squadre possono scambiarsi giocatori tra loro.
Il tetto delle operazioni è dato dal parametro max_trades del modello League.
Tale parametro viene mutuato da Team e va a scalare ad ogni operazione effettuata.
Per tenere traccia delle operazioni di mercato, aggiungeremo un modello
a quelli già esistenti.

add_trade

fantalega/models.py

...
class Trade(models.Model):
    league = models.ForeignKey(League, related_name='trades')
    player = models.ForeignKey(Player)
    team = models.ForeignKey(Team)
    direction = models.CharField(max_length=3)  # IN or OUT value

    def __unicode__(self):
        return "[%s] %s: %s" % (self.direction, self.team.name,
                                self.player.name)

Trade è legato a League, Player e Team da relazioni many-to-one.
Il fatto che un giocatore sia in uscita o in entrata, è definito
dal campo ‘direction’.

Aggiornare il database inserendo le nuove tabelle.

(venv) >python manage.py makemigrations
Migrations for 'fantalega':
  fantalega\migrations\0007_trade.py:
    - Create model Trade

confermare con:

(venv) C:\tmp\djangosite>python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, fantalega, log, sessions
Running migrations:
  Applying fantalega.0007_trade... OK

Aggiungere per prima cosa le urls relative ai mercati (Trade) nel file fantalega\urls.py:

...
    # trade urls
    url(r'^leagues/(?P<league_id>[0-9]+)/trades/$',
        views.trades, name='trades'),
    url(r'^leagues/(?P<league_id>[0-9]+)/teams/(?P<team_id>[0-9]+)/trade$',
        views.trade, name='trade'),
]

Abilitare le interfacce di admin in fantalega\admin.py:

...
from .models import Trade
from django.utils.html import format_html

...
class TradeAdmin(admin.ModelAdmin):
    list_display = ('direction', 'colored_player', 'team')
    list_filter = ('direction', 'team')
    list_per_page = 20

    @staticmethod
    def colored_player(obj):
        colour = '013ADF' if obj.direction == 'IN' else 'FF0080'
        return format_html('<span style="color: #{};">{}</span>',
                           colour, obj.player.name)
...
admin.site.register(TradeAdmin)

Aggiungere nel file fantalega\views.py le nuove viste:

...
from .models import Trade
...
@login_required
def trades(request, league_id):
    league = get_object_or_404(League, pk=int(league_id))
    if request.GET.get('back_to_teams'):
        return redirect('league_details', league.id)
    context = {'trades': Trade.objects.all(), 'league': league}
    return render(request, 'fantalega/trades.html', context)


@login_required
def trade(request, league_id, team_id):
    league = get_object_or_404(League, pk=int(league_id))
    team = get_object_or_404(Team, pk=int(team_id))
    if request.GET.get('back_to_team_details'):
        return redirect('team_details', league.id, team.id)
    team_players = [(p.code, "%s (%s)" % (p.name, p.role))
                    for p in team.player_set.all()]
    others = [(p.code, "%s (%s) --- %s" % (p.name, p.role, p.team.name))
              for p in Player.objects.order_by('name') if p.team and p not
              in team.player_set.all()]
    if request.method == "POST":
        form = TradeForm(request.POST, initial={'players': team_players,
                                                'others': others,
                                                'league': league})
        if form.is_valid():
            player_out_code = form.cleaned_data['player_out']
            player_out = Player.get_by_code(int(player_out_code),
                                            season=league.season)
            player_in_code = form.cleaned_data['player_in']
            player_in = Player.get_by_code(int(player_in_code),
                                           season=league.season)
            team.max_trades -= 1
            other_team = player_in.team
            other_team.max_trades -= 1
            if team.max_trades >= 0 and other_team.max_trades >= 0:
                player_in.team = team
                player_out.team = other_team
                if player_in.role == player_out.role:
                    player_in.save()
                    player_out.save()
                    team.save()
                    other_team.save()
                    Trade.objects.create(player=player_out, team=team,
                                         direction="OUT", league=league)
                    Trade.objects.create(player=player_in, team=team,
                                         direction="IN", league=league)
                    Trade.objects.create(player=player_out, team=other_team,
                                         direction="IN", league=league)
                    Trade.objects.create(player=player_in, team=other_team,
                                         direction="OUT", league=league)
                    messages.success(request,
                                     'Trade operation %s: --> '
                                     '[OUT] %s [IN] %s stored!' %
                                     (team, player_out.name, player_in.name))
                    messages.success(request,
                                     'Trade operation %s: --> '
                                     '[OUT] %s [IN] %s stored!' %
                                     (other_team, player_in.name,
                                      player_out.name))
                else:
                    messages.error(request,
                                   'Players MUST have the same role, aborted!')

            else:
                messages.error(request,
                               "Not enough trade operations: "
                               "%s [%s] and %s [%s]" %
                               (team.name, team.max_trades, other_team.name,
                                other_team.max_trades))
            return redirect('team_details', league.id, team.id)
    else:
        form = TradeForm(initial={'players': team_players, 'others': others,
                                  'league': league})
    return render(request, 'fantalega/trade.html',
                  {'form': form, 'players': team_players, 'others': others,
                   'team': team, 'league': league})

il form che permetterà di effettuare un’operazione di mercato sarà:

...
class TradeForm(forms.Form):
    def __init__(self, *args, **kwargs):
        self.dict_values = kwargs.pop('initial')
        super(TradeForm, self).__init__(*args, **kwargs)
        self.fields['player_out'] = forms.ChoiceField(
            label=u'OUT', choices=self.dict_values['players'],
            widget=forms.Select(), required=False)
        self.fields['player_in'] = forms.ChoiceField(
            label=u'IN', choices=self.dict_values['others'],
            widget=forms.Select(), required=False)

e andrà importato nel file fantalega/views.py:

from .forms import TradeForm
...

Il bottone ‘new trade’ che appare nella template team.html, va
abilitato nella view team_details:

...
@login_required
def team_details(request, league_id, team_id):
    ...
    if request.GET.get('new trade'):
        return redirect('trade', league.id, team.id)
    return render(request, 'fantalega/team.html', context)

mentre il bottone ‘view trades’ che appare nella template league.html, va
abilitato nella view league_details:

...
@login_required
def league_details(request, league_id):
    ...
    if request.GET.get('trades'):
        return redirect('trades', league.id)
    ...
    return render(request, 'fantalega/league.html', context)

Le templates saranno invece:
fantalega/templates/fantalega/trades.html

{% extends 'fantalega/base.html' %}

{% block content %}
    <b>List of all trade operations for <font color="green">
        {{ league.name }}</font></b>
    <br><br>
    <form action="#" method="get">
    <input type="submit" class="btn"
           value="back to {{ league.name }} details" name="back_to_teams">
    </form>

    {% if trades %}
        <table class="table table-striped" width="100%">
          <tr>
              <th>in/out</th>
              <th>name</th>
              <th>team</th>
          </tr>
          <tr>
          {% for trade in trades %}
              <td>{{ trade.direction }}</td>
              <td><a href="{% url 'team_details' league.id trade.team.id %}">
                  {{ trade.team.name }}</a></td>
              <td><a href="{% url 'player_details' trade.player.id %}">
                  {{ trade.player.name }}</a></td>
          </tr>
          {% endfor %}
        </table>
    {% else %}
        <font color="red"><b>No trade operations found.</b></font>
    {% endif %}
{% endblock %}

fantalega/templates/fantalega/trade.html

{% extends 'fantalega/base.html' %}
{% load bootstrap3 %}

{% block content %}
    <b>New Trade Operation for team: <font color="green">{{ team.name }}</font></b>
    <br><br>
    <form action="#" method="get">
    <input type="submit" class="btn"
           value="back to {{ team.name }} team" name="back_to_team_details">
    </form>

    <form method="POST" class="form">
		{% csrf_token %}
        {% bootstrap_form form %}
            {% buttons %}
                <button type="submit" class="btn btn-primary">
                {% bootstrap_icon "save" %} Submit</button>
			{% endbuttons %}
    </form>
{% endblock %}

Prima che venga salvata l’operazione di scambio, verranno controllati:
– i ruoli dei giocatori (devono essere gli stessi)
– il numero di operazioni rimaste.

Salvare gli avanzamenti su github:

git add --all
git commit -m "Trade added"
git push -u origin master

articoli precedenti
0 – indice
1 – Virtualenv e Git
2 – Models: Season
3 – Admin: Login and Logout
4 – Models: League
5 – Models: Team
6 – Models: Match
7 – Models: Player e Evaluation
8 – Asta
9 – Models: Lineup

articoli successivi
11 – Asta di riparazione
12 – Classifica

Categorie:Django Tag:
  1. Al momento, non c'è nessun commento.
  1. novembre 14, 2016 alle 4:02 PM
  2. novembre 14, 2016 alle 4:05 PM
  3. novembre 14, 2016 alle 4:07 PM
  4. novembre 14, 2016 alle 4:08 PM
  5. novembre 15, 2016 alle 12:36 PM
  6. novembre 15, 2016 alle 12:37 PM
  7. novembre 15, 2016 alle 12:37 PM
  8. novembre 15, 2016 alle 12:37 PM
  9. novembre 15, 2016 alle 12:37 PM
  10. novembre 15, 2016 alle 12:38 PM
  11. novembre 15, 2016 alle 12:38 PM
  12. novembre 18, 2016 alle 10:18 PM

Lascia un commento