在模板Django Rest框架中使用searializer字段

在模板Django Rest框架中使用searializer字段,django,django-rest-framework,Django,Django Rest Framework,我不熟悉Django Rest框架,也不熟悉编写第一个API应用程序 my联系人/型号.py class Contact(models.Model): user_id = models.ForeignKey(User, on_delete=models.CASCADE) first_name = models.CharField(max_length=100) last_name = models.CharField(max_length=100, blank=True,

我不熟悉Django Rest框架,也不熟悉编写第一个API应用程序

my联系人/型号.py

class Contact(models.Model):
    user_id = models.ForeignKey(User, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100, blank=True, null=True)
    date_of_birth = models.DateField(blank=True, null=True)

    class Meta:
        db_table = 'contacts'

    def full_name(self):
        return self.first_name + ' ' + self.last_name

    def __str__(self):
        return self.full_name()


class ContactEmail(models.Model):
    contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
    email = models.EmailField()
    primary = models.BooleanField(default=False)

    class Meta:
        db_table = 'contact_emails'

    def __str__(self):
        return self.email
class ContactSerializer(serializers.HyperlinkedModelSerializer):
    primary_email = serializers.SerializerMethodField()

    class Meta:
        model = Contact
        fields = ('url', 'full_name', 'date_of_birth', 'primary_email')

    def get_primary_email(self, obj):
        primary_email = obj.contactemail_set.filter(primary=True).first()

        if primary_email:
            return primary_email.email

        return ''
class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly,)

    def perform_create(self, serializer):
        serializer.save(user_id=self.request.user)

class ContactList(APIView):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'contacts/list.html'
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def get(self, request):
        queryset = Contact.objects.all()
        return Response({'contacts': queryset})
联系人/searializers.py

class Contact(models.Model):
    user_id = models.ForeignKey(User, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100, blank=True, null=True)
    date_of_birth = models.DateField(blank=True, null=True)

    class Meta:
        db_table = 'contacts'

    def full_name(self):
        return self.first_name + ' ' + self.last_name

    def __str__(self):
        return self.full_name()


class ContactEmail(models.Model):
    contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
    email = models.EmailField()
    primary = models.BooleanField(default=False)

    class Meta:
        db_table = 'contact_emails'

    def __str__(self):
        return self.email
class ContactSerializer(serializers.HyperlinkedModelSerializer):
    primary_email = serializers.SerializerMethodField()

    class Meta:
        model = Contact
        fields = ('url', 'full_name', 'date_of_birth', 'primary_email')

    def get_primary_email(self, obj):
        primary_email = obj.contactemail_set.filter(primary=True).first()

        if primary_email:
            return primary_email.email

        return ''
class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly,)

    def perform_create(self, serializer):
        serializer.save(user_id=self.request.user)

class ContactList(APIView):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'contacts/list.html'
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def get(self, request):
        queryset = Contact.objects.all()
        return Response({'contacts': queryset})
联系人/视图.py

class Contact(models.Model):
    user_id = models.ForeignKey(User, on_delete=models.CASCADE)
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100, blank=True, null=True)
    date_of_birth = models.DateField(blank=True, null=True)

    class Meta:
        db_table = 'contacts'

    def full_name(self):
        return self.first_name + ' ' + self.last_name

    def __str__(self):
        return self.full_name()


class ContactEmail(models.Model):
    contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
    email = models.EmailField()
    primary = models.BooleanField(default=False)

    class Meta:
        db_table = 'contact_emails'

    def __str__(self):
        return self.email
class ContactSerializer(serializers.HyperlinkedModelSerializer):
    primary_email = serializers.SerializerMethodField()

    class Meta:
        model = Contact
        fields = ('url', 'full_name', 'date_of_birth', 'primary_email')

    def get_primary_email(self, obj):
        primary_email = obj.contactemail_set.filter(primary=True).first()

        if primary_email:
            return primary_email.email

        return ''
class ContactViewSet(viewsets.ModelViewSet):
    queryset = Contact.objects.all()
    serializer_class = ContactSerializer
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                          IsOwnerOrReadOnly,)

    def perform_create(self, serializer):
        serializer.save(user_id=self.request.user)

class ContactList(APIView):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'contacts/list.html'
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def get(self, request):
        queryset = Contact.objects.all()
        return Response({'contacts': queryset})
其中,
ContactViewSet
可通过
http://:/api/contacts
访问,
ContactList
可通过
http://:/contacts

http://:/api/contacts
在json响应中给出了primary\u电子邮件,但在list.html中使用时它不会打印任何内容
{{contact.primary\u email}

使用**APIView时,我不能使用序列化程序字段吗**

我是否需要重写
联系人列表()中的函数以获取主\u电子邮件字段?

编辑2:
contacts/list.html

{%用于联系人%}
{{contact.full_name}
{{contact.primary_email}
{%endfor%}

这是打印用户的全名,但不是主要电子邮件

您必须使用
APIView
中的序列化程序才能访问其字段。您还需要使用Django
render
helper在上下文中传递联系人,以便呈现模板,因为
APIView
不知道如何呈现自定义模板

一种选择是在将数据添加到联系人列表的上下文之前序列化数据。大概是这样的:

from django.shortcuts import render


class ContactList(APIView):
    renderer_classes = [TemplateHTMLRenderer]
    template_name = 'contacts/list.html'
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def get(self, request):
        serialized_contacts = ContactSerializer(
            Contact.objects.all(), many=True).data
        context = {'contacts': serialized_contacts}
        return render(request, self.template_name, context)
但我看不出在该视图中使用APIView或序列化程序的理由。我要做的是:

  • 主要\u电子邮件
    属性添加到
    联系人
    模型:

    class Contact(models.Model):
        user_id = models.ForeignKey(User, on_delete=models.CASCADE)
        first_name = models.CharField(max_length=100)
        last_name = models.CharField(max_length=100, blank=True, null=True)
        date_of_birth = models.DateField(blank=True, null=True)
    
        class Meta:
            db_table = 'contacts'
    
        @property
        def full_name(self):
            return self.first_name + ' ' + self.last_name
    
        @property
        def primary_email(self):
            primary_email = self.contactemail_set.filter(primary=True).first()
    
            if primary_email:
                return primary_email.email
    
            return ''
    
        def __str__(self):
            return self.full_name
    
  • 使用此新模型,无需在ContactSerializer
  • 中定义
    get\u primary\u email
    方法:

    class ContactSerializer(serializers.HyperlinkedModelSerializer):
        primary_email = serializers.SerializerMethodField()
    
        class Meta:
            model = Contact
            fields = ('url', 'full_name', 'date_of_birth', 'primary_email')
    
  • 我将使用Django的generics.ListView,而不是使用
    APIView
    查看
    ContactList

    from django.views.generic import ListView
    from django.contrib.auth.mixins import LoginRequiredMixin
    
    
    class ContactList(LoginRequiredMixin, ListView):
        template_name = 'contacts/list.html'
        permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
        queryset = Contact.objects.all()
    

  • 是否可以查看
    联系人/list.html
    ?请参阅
    编辑2
    。添加了
    contacts/list.html
    是的,我在模型类中添加了函数,从
    APIView
    API
    可以很容易地使用,但是我仍然需要回答这个问题,因为可能有很多函数我不能直接在模型中编写。你的答案在那一刻会派上用场的。