我无法理解Django中ManyToMany字段列表的函数

osh3o9ms  于 2023-05-23  发布在  Go
关注(0)|答案(1)|浏览(153)

没有自动列出的类似问题回答我的问题:
我有models.py如下:

```from django.db import models

class Location(models.Model):
    name = models.CharField(max_length=200)
    address = models.CharField(max_length=300)

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

class Participant(models.Model):
    email = models.EmailField(unique=True)

    def __str__(self):
        return self.email
  
class Meetup(models.Model):
    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)
    description = models.TextField()
    image = models.ImageField(upload_to='images')
    location = models.ForeignKey(Location, on_delete=models.CASCADE)
    participants = models.ManyToManyField(Participant)
    
    def __str__(self):
        return f'{self.title} - {self.slug} - {self.description}'```

为了能够列出我通过管理面板输入的两封电子邮件,我有以下Admin.py

```from django.contrib import admin
from .models import Meetup, Location, Participant
# Register your models here.

class MeetupAdmin(admin.ModelAdmin):
    list_display = ('title', 'slug', 'description', 'location', 'get_emails')

    def get_emails(self, obj):
        return "\n".join([p.email for p in obj.participants.all()])

    list_filter = ('title', 'description')

    prepopulated_fields = {'slug': ('title', )}

    search_fields = ('title', )

admin.site.register(Meetup, MeetupAdmin)
admin.site.register(Location)
admin.site.register(Participant)```

不使用函数

return "\n".join([p.email for p in obj.participants.all()])```

I would not have been able to list the two emails represented by the ManyToMany relation 

My question here is: I would like to understand what does the p and obj here. I would be so grateful if someone could explain how this work.
5lwkijsr

5lwkijsr1#

您可以在list_display中传递方法的名称,在这种情况下,对于ModelAdmin将显示的每个记录,它将调用带有obj的函数,该对象是它想要呈现内容的对象。
这里obj是一个Meetup对象,你可以访问一个ManyToManyField,所以obj.participants.all()将返回所有链接到MeetupParticipant。我们在这里使用列表解析来生成一个.email s的列表,然后使用'\n'.join(…)来创建一个字符串,我们用新行('\n')分隔电子邮件地址。
但是,这并不是很有效:如果Meetup的数量将增长,这将导致大量的查询。您可以使用以下命令在 one extra query中选择所有相关的Participant

class MeetupAdmin(admin.ModelAdmin):
    list_display = ('title', 'slug', 'description', 'location', 'get_emails')
    list_filter = ('title', 'description')
    prepopulated_fields = {'slug': ('title',)}
    search_fields = ('title',)

    def get_queryset(self, request):
        return super().get_queryset(request).prefetch_related('participants')

    def get_emails(self, obj):
        return '\n'.join([p.email for p in obj.participants.all()])

相关问题