【问题标题】:How to select an instance of a model from a queryset django?如何从查询集 django 中选择模型的实例?
【发布时间】:2020-10-02 18:40:55
【问题描述】:

我正在创建一个用于举办板球锦标赛的项目。我在其中创建了 3 个应用程序:家庭、锦标赛和团队。添加锦标赛后,当进入锦标赛的详细视图时,我可以将团队添加到锦标赛中。我的Team 模型对我的Tournament 模型有一个 ForeignKey,我的Tournament 模型对我的User 模型有一个 ForeignKey(内置 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.x django django-models django-forms django-views


    【解决方案1】:

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

     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] (或任何数字),还有更多

    【讨论】:

    • 我已经尝试过这样的事情,但问题是可能存在属于用户(父模型)的各种锦标赛(子模型)。那么如何将我进入 addteam 页面的特定锦标赛指定为团队的父级?
    • @Rohan,如果您通过锦标赛访问“addteam”页面,请获取该锦标赛的 id 并在 .get() 中使用它。像这样:Tournament.objects.get(id=1)。 id 字段应该是唯一的,所以你不应该有问题。也许可以修改 Team 应用程序中“addteam”url 的路径,并在 url 路径中包含一个 id 变量(锦标赛的),以便您可以从那里获取它。
    • 是的,确实有效。我将 url 中的比赛 pk 发送到 addteam,得到它以获得确切的比赛,并将球队添加到比赛中。在我的 addteam html 页面的 form 标记中,我删除了 action 属性。
    猜你喜欢
    • 2015-06-17
    • 2020-04-17
    • 1970-01-01
    • 2012-04-17
    • 1970-01-01
    • 1970-01-01
    • 2011-08-06
    • 2014-09-21
    • 1970-01-01
    相关资源
    最近更新 更多