首页 > 解决方案 > 如何从查询集 django 中选择模型的实例?

问题描述

我正在创建一个举办板球锦标赛的项目。我在其中创建了 3 个应用程序:家庭、锦标赛和团队。添加锦标赛后,当进入锦标赛的详细视图时,我可以将团队添加到锦标赛中。我的Team模型对我的模型有一个 ForeignKey,我的Tournament模型对我的Tournament模型有一个 ForeignKey User(内置 django 用户模型)。创建团队时,我想为特定锦标赛保存团队。我不明白如何访问确切的锦标赛并仅为该锦标赛保存球队。

我的比赛详情 html:

    {% extends 'menu.html' %}

    {% block content %}
<div class="row">
    <div class="col-8">
        <table class="table table-bordered table-hover">
        <tr>
            <th scope="col">Match between</th>
            <th scope="col">Winner</th>
        </tr>
        {% for match in match_list %}
            <tr>
                <td>
                    {{ match.team1.name }} vs {{ match.team2.name }}
                </td>
                <td>
                    {% if match.winner %}
                        {{ match.winner.name }}
                    {% else %}
                        TBD
                    {% endif %}
                </td>
            </tr>
        {% endfor %}
        </table>
    </div>
    <div class="col-4">
        {% if teamscount < tournament.no_of_teams %}
            <button class="btn btn-primary" onclick="window.location.href='{% url 'teams:addteam' %}'">Add Team</button>
        {% endif %}
    </div>
</div>

    {% endblock content %}

我在锦标赛应用程序中的 urls.py 文件:

    from django.urls import path, include
    from . import views

    app_name='tournaments'
    urlpatterns = [
        path('all/', views.TournamentListView.as_view(), name='all'),
        path('create/', views.TournamentCreateView.as_view(), name='create'),
        path('view/<int:pk>/', views.TournamentDetailView.as_view(), name='detail'),
    ] 

我在团队应用程序中的 urls.py 文件:

    from django.urls import path
    from . import views

    app_name="teams"
    urlpatterns = [
        path('new/', views.TeamCreateView.as_view(), name="addteam"),
    ]

我在团队应用程序中的 views.py 文件:

    from django.shortcuts import render
    from django.views.generic import CreateView
    from .models import Team
    from django.urls import reverse_lazy
    from tournament.models import Tournament

    class TeamCreateView(CreateView):
        model = Team
        fields = ['name', 'no_of_players',]
        success_url = reverse_lazy('tournaments:all')
        success_message = "Tournament Created!!"

        def get_form(self):
            form = super().get_form()
            return form
 
       def form_valid(self, form):
            print('form_valid called')
            object = form.save(commit=False)
            object.tournament = Tournament.objects.filter(user = self.request.user)
            object.save()
            return super(TeamCreateView, self).form_valid(form)

我的创建团队 html 文件:

    {% extends 'menu.html' %}
    {% load crispy_forms_tags %}
    {% block content %}
    {% load bootstrap4 %}
    {% bootstrap_css %}
    {% bootstrap_javascript jquery='full' %}
    {{ form.media }}
    <form
        action="{% url 'teams:addteam' %}"
        method="post"
        id="upload_form"
        enctype="multipart/form-data"
    >
         {% csrf_token %} {{ form|crispy }}
         <div class="form-group">
         <button class="btn btn-outline-info" type="submit">Create</button>
         <input class="btn btn-danger" type="submit" onclick="window.location='{% url 'tournaments:all' %}' ; return false;" value="Cancel" />
         </div>
         </form>
    {% endblock content %}

如何将这支球队保存到特定的锦标赛模型中,或者我是否需要更改我设计函数和类的方式?

标签: python-3.xdjangodjango-modelsdjango-formsdjango-views

解决方案


据我了解,您的模型具有以下设计:

 class Tournament(models.Model):
    name = models.CharField(max_length=50)
    user = models.ForeignKey(
            get_user_model(),
            on_delete=models.CASCADE
    )

    def __str__(self):
        return self.name

class Team(models.Model):
    name = models.CharField(max_length=50)
    tournament = models.ForeignKey(Tournament, on_delete=models.CASCADE)

    def __str__(self):
        return self.name

因此,如果要将 Team 实例保存到特定锦标赛,则需要执行以下操作:

# Grab the tournament instance in a variable (I recommend to use the id instead of the user. This is probably better, unless the user is unique per tournament, if not .get() will throw an error )
tournament = Tournament.objects.get(user=user)
# Then create your Team object like this
Team.objects.create(name='super team', tournament=tournament)

我看到的问题之一是您单独使用“过滤器”来尝试获取实例。“过滤器”返回一个查询集。使用“过滤器”后,您有很多选择来返回特定实例,您可以执行 .filter().first() 或 .filter()[0] (或任何数字),还有更多


推荐阅读