【问题标题】:Django Advanced ModelDjango 高级模型
【发布时间】:2021-10-28 07:08:15
【问题描述】:

我有 2 个模型。在其中一个中,我想撤回一般信息,而在另一个 - 高级信息中。 我希望模型结合 service_id 字段。

在 AdvancedService 模型中,我有 2 个对象和一个 service_id。在服务模型中,当我单击 service_id 时,我想查看 2 个具有此类 service_id 的对象。但是,我不明白如何做到这一点。我的代码:

#models.py

class ServiceModel(models.Model):
    service_id = models.CharField(max_length=150)
    total_cars = models.PositiveIntegerField() # bmw + audi
    repaired = models.PositiveIntegerField() # broken_motor + broken_body
    advanced = models.ForeignKey(
        'AdvancedServiceModel', on_delete=models.CASCADE)

class AdvancedServiceModel(models.Model):
    service_id = models.CharField(max_length=150)
    bmw = models.PositiveIntegerField()
    audi = models.PositiveIntegerField()
    broken_motor = models.PositiveIntegerField()
    broken_body = models.PositiveIntegerField()

    def __str__(self) -> str:
        return f'{self.service_id}'

#admin.py

from django.contrib import admin
from .models import ServiceModel, AdvancedServiceModel
from django.urls import reverse
from django.utils.html import escape, mark_safe

@admin.register(ServiceModel)
class ServiceModelAdmin(admin.ModelAdmin):
    list_display = ['advanced_link', 'total_cars', 'repaired']

    def advanced_link(self, obj: AdvancedServiceModel):
        link = reverse("admin:tasks_advancedservicemodel_changelist")
        return mark_safe(f'<a href="{link}">{escape(obj.advanced.__str__())}</a>')

    advanced_link.short_description = 'Service id'
    advanced_link.admin_order_field = 'service_id' # Make row sortable

@admin.register(AdvancedServiceModel)
class AdvancedServiceModelAdmin(admin.ModelAdmin):
    list_display = ['service_id', 'bmw', 'audi', 'broken_motor', 'broken_body']

【问题讨论】:

  • 请澄清您的具体问题或提供其他详细信息以准确突出您的需求。正如目前所写的那样,很难准确地说出你在问什么。
  • 我的问题已经给出了答案。

标签: django django-models django-views django-forms django-admin


【解决方案1】:

我的回答要求ServiceModel.service_id 是唯一的。您应该将外键从ServiceModel 移动到AdvancedServiceModel。这是因为您需要一个服务模型实例用于所有高级服务模型。 Django 没有OneToManyField。只能通过ForeignKey实现。

作为此更改的一部分,您将从AdvancedServiceModel 中删除service_id 字段。如果您需要获取实际的服务 ID,则需要拉取关联的 ServiceModel

class ServiceModel(models.Model):
    service_id = models.CharField(max_length=150, unique=True)
    total_cars = models.PositiveIntegerField() # bmw + audi
    repaired = models.PositiveIntegerField() # broken_motor + broken_body


class AdvancedServiceModel(models.Model):
    service_model = models.ForeignKey(
        ServiceModel, related_name='advanced_service_models', on_delete=models.CASCADE)
    bmw = models.PositiveIntegerField()
    audi = models.PositiveIntegerField()
    broken_motor = models.PositiveIntegerField()
    broken_body = models.PositiveIntegerField()

# admin.py
from django.db.models import Count

@admin.register(ServiceModel)
class ServiceModelAdmin(admin.ModelAdmin):
    list_display = ['advanced_link', 'total_cars', 'repaired']

    def get_queryset(self, *args, **kwargs): # I forget the arguments, look them up please.
        return super().get_queryset(*args, **kwargs).annotate(
            advanced_count=Count('advanced_service_models__id'),
        )

    def advanced_link(self, obj: AdvancedServiceModel):
        link = reverse("admin:tasks_advancedservicemodel_changelist") + f"?service_model__id__exact={obj.id}"
        count = obj.advanced_count
        return mark_safe(f'<a href="{link}">View Advanced Services ({count})</a>')

    advanced_link.short_description = 'Service id'
    advanced_link.admin_order_field = 'service_id' # Make row sortable

@admin.register(AdvancedServiceModel)
class AdvancedServiceModelAdmin(admin.ModelAdmin):
    list_display = ['service_id', 'bmw', 'audi', 'broken_motor', 'broken_body']
    list_select_related = ['service_model']
    
    def service_id(self, obj):
        return obj.service_model.service_id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-25
    • 2012-11-07
    • 2011-09-17
    • 2015-01-04
    • 1970-01-01
    • 1970-01-01
    • 2012-10-19
    • 2015-12-09
    相关资源
    最近更新 更多