Django 高级模型
Django Advanced Model
我有 2 个模型。在其中一个中,我想撤回一般信息,在另一个中,我想撤回高级信息。
我希望模型结合 service_id 字段。
在 AdvancedService 模型中,我有 2 个对象和一个 service_id。在服务模型中,当我单击 service_id 时,我想查看 service_id 这样的 2 个对象。但是,我不明白该怎么做。我的代码:
#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']
我的回答要求 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
我有 2 个模型。在其中一个中,我想撤回一般信息,在另一个中,我想撤回高级信息。 我希望模型结合 service_id 字段。
在 AdvancedService 模型中,我有 2 个对象和一个 service_id。在服务模型中,当我单击 service_id 时,我想查看 service_id 这样的 2 个对象。但是,我不明白该怎么做。我的代码:
#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']
我的回答要求 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