Django - 使用传递给 URL 的父 class 主键过滤来自子 class 的对象

Django - Filter objects from child class with parent class primary key passed in URL

我正在尝试在车辆详细信息 html 页面中传递为每辆车发布的所有帖子。

我的vehicles/models.py:

*vehicles/models.py*

class Vehicle(models.Model):

     
    TESLA = 'TESLA'
    MAZDA = 'MAZDA'
    VOLVO = 'VOLVO'
    VEHICLE_CHOICES = (
        (TESLA, "Tesla"),
        (MAZDA, "Mazda"),
        (VOLVO, "Volvo"),
        )

    owner =  models.ForeignKey(User, on_delete=models.CASCADE) 
    
    model = models.CharField(max_length=9,
       
                    choices=VEHICLE_CHOICES,
                    default=TESLA)

    def __str__(self):
            return self.model

    class Meta:
        db_table = "vehicles"

我的帖子 models.py:

*blog/models.py*

from django.db import models
from django.contrib.auth.models import User


     
class Post(models.Model):
    date_posted = models.DateTimeField(default=timezone.now)
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    vehicle =  models.ForeignKey(Vehicle, on_delete=models.CASCADE, default=None )
    
    def get_absolute_url(self):

        return reverse('post-detail', kwargs ={'pk': self.pk} )
  
    class Meta:
        db_table = "chargehistory"

我已经为每个用户传递了一个 html 文件,现在我想获取为每个用户的车辆发布的所有帖子。

*vehicles/views.py*

class UserVehicleListView(ListView):
    model = Vehicle
    template_name = 'vehicles/vehicles.html'  # <app>/<model>_<viewtype>.html
    context_object_name = 'vehicles'
    
    def get_queryset(self):
        return Vehicle.objects.filter(owner_id= self.request.user.id)

class UserVehicleDetailView(DetailView):
    model = Vehicle


*vehicles/urls.py*



urlpatterns = [
    path('vehicles', UserVehicleListView.as_view(), name='vehicle-list'),
    path('vehicles/<int:pk>',  UserVehicleDetailView.as_view() , name='vehicle-detail'),

]

urlpatterns += staticfiles_urlpatterns()


由于我在路径中传递车辆主键,我有什么方法可以根据该键过滤帖子并将其传递给 vehicle_detail.html?我应该将它作为 ListView 传递到与 UserVehicleDetailView 相同的路径中吗?

您可以直接使用您使用的DetailView[django-doc]。 urls.py 中 DetailViewroute 是正确的。您必须从 html 部分传递它的 pk。

views.py

class UserVehicleDetailView(DetailView):
    model=Vehicle
    template_name="any_folder_name/any_file.html"
    context_object_name="single_vehicle"

Note: While using DetailView you should not run loop, as it is a single object.

anyfile.html


{% if "single_vehicle" %}
    <p>{{single_vehicle.owner.username}}</p>
{% endif %}

在这里,你可以通过链接访问他的所有属性,你也可以把pk改成另一个名字,比如id,然后在你的UserVehicleDetailView中提到它作为pk_url_kwarg="id",那么它也可以工作。

但一开始需要通过循环将pk通过ListView传递,然后通过DetailView.

将其作为单个对象访问

Note: Always give / at the end of every route in path function.




这是最小的可重现示例:

创建一个简单的项目,其中制作一个名为 home 的应用程序,在 settings.py 中的 INSTALLED_APPS 中注册它。之后看下面的例子:

models.py

from django.db import models

class Subject(models.Model):
    name = models.CharField(max_length=200)

    def __str__(self):
        return f"{self.name}"

    class Meta:
        ordering = ['name']

class Student(models.Model):
    name = models.CharField(max_length=100)
    email = models.CharField(max_length=200)
    father_name = models.CharField(max_length=200)
    subject = models.ForeignKey(Subject, on_delete=models.CASCADE)

    def __str__(self):
        return f"{self.name}"

urls.py

from django.urls import path
from . import views
urlpatterns = [
    path('', views.AllStudentDetailView.as_view(), name='all_student_detail'),
    path('single_student/<int:id>/',
         views.SingleStudentView.as_view(), name='student_detail')
]

views.py

from msilib.schema import ListView
from django.shortcuts import render
from django.views.generic import DetailView, ListView
from .models import Student


class AllStudentDetailView(ListView):
    model = Student
    template_name = 'home/list_of_students.html'
    context_object_name = 'all_students'


class SingleStudentView(DetailView):
    model = Student
    template_name = 'home/single_student.html'
    context_object_name = 'student'
    pk_url_kwarg = 'id'

Note: In DetailView there is also use of pk_url_kwarg, this is used when we give something else than pk.

admin.py

from django.contrib import admin
from .models import Student, Subject


@admin.register(Subject)
class SubjectAdmin(admin.ModelAdmin):
    list_display = ['id', 'name']


@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'email', 'father_name', 'subject']

list_of_students.html

<body>
    <h2>All Student Details</h2>
    <table border='1' style='text-align:center;' cellpadding='3px' cellspacing='3px'>
        <thead>
            <tr>
                <th>Name</th>
                <th>Email</th>
                <th>Father Name</th>
                
            </tr>
        </thead>
        <tbody>
            {% for student in all_students  %}
            <tr>
                <td><a href="{% url 'student_detail' student.id %}">{{student.name}}</a></td>
                <td>{{student.email}}</td>
                <td>{{student.father_name}}</td>

            </tr>
            {% endfor %}
        </tbody>

    </table>
</body>

single_student.html

<body>
    {% if student %}
    <h2>Detail of {{student.name}}</h2>
    <h3>All subject he/she had taken are:</h3>

    <p>Subject is -- {{student.subject}}</p>

    {% else %}
    <p>Student object does not come.</p>
    {% endif %}
</body>

当您单击单个学生的姓名时,您将被重定向到在详细信息页面上查看其详细信息。