代码之家  ›  专栏  ›  技术社区  ›  Anuj TBE

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

  •  0
  • Anuj TBE  · 技术社区  · 6 年前

    我是新手 Django Rest Framework 编写第一个API应用程序。

    我的 联系人/型号。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
    

    联系人/搜索器。py公司

    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 ''
    

    联系人/视图。py公司

    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://<ip>:<port>/api/contacts ContactList 可通过访问 http://<ip>:<port>/contacts

    http://<ip>:<端口(>)/api/联系人 正在给予 primary\u电子邮件 在json响应中,但在 列表html {{ contact.primary_email }}

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

    是否需要重写 ContactList() 要获取primary\u电子邮件字段?

    编辑2: contacts/list.html

    {% for contact in contacts %}
        <h4 class="card-title">{{ contact.full_name }}</h4>
        <h5>{{ contact.primary_email }}
        <a href="{% url 'contact:detail' contact.pk %}">Click here</a>
    {% endfor %}
    

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

    1 回复  |  直到 6 年前
        1
  •  1
  •   hugobessa    6 年前

    您必须在中使用序列化程序 APIView 访问其字段。您还需要使用Django render 助手在上下文中传递联系人以呈现模板,因为 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或序列化程序。我会做什么:

    1. 添加一个 primary_email 属性到 Contact 型号:

      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
      
    2. 有了这个新模型,就没有必要 get_primary_email 中定义的方法 ContactSerializer :

      class ContactSerializer(serializers.HyperlinkedModelSerializer):
          primary_email = serializers.SerializerMethodField()
      
          class Meta:
              model = Contact
              fields = ('url', 'full_name', 'date_of_birth', 'primary_email')
      
    3. 而不是使用 APIView 对于 ContactList 视图中,我会使用Django的泛型。ListView。

      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()