python - 从 django rest 框架中使用 api

标签 python django rest django-rest-framework

我已经使用 django rest api 创建了一个看起来像这样的 api -

{
"count": 2,
"next": null,
"previous": null,
"results": [
    {
        "url": "http://127.0.0.1:8000/app/student/1/",
        "id": 1,
        "title": "mr",
        "name": "student1",
        "address": "somewhere",
        "city": "Mumbai",
        "tests": [
            {
                "test_name": "Math",
                "section_1": "34",
                "section_2": "54",
                "date_added": "2015-12-15"
            }
        ]
    },
    {
        "url": "http://127.0.0.1:8000/app/student/2/",
        "id": 2,
        "title": "mr",
        "name": "student2",
        "address": "somewhere",
        "city": "Delhi",
        "tests": [
            {
                "test_name": "English",
                "section_1": "34",
                "section_2": "65",
                "date_added": "2015-12-15"
            }
        ]
    }
   ]
 }

我在同一个项目中有另一个应用程序使用这样的数据 -

def Peoplelist(request):
    data= requests.get('http://127.0.0.1:8000/app/students/').json()
    send_list = []
    for i in range(2):
        send_list.append(data['results'][i]['name'])
    context = RequestContext(request, {
    'send_list': send_list,
})
return render_to_response('taskmanager/numbers.html', context)

创建一个学生姓名列表。

我想根据城市名称显示学生姓名列表,然后单击姓名以查看学生和测试详细信息。不知道该怎么做。有人可以建议一种方法吗?谢谢。

models.py
class Test(models.Model):
    date_added = models.DateField(default=datetime.datetime.now)
    test_name = models.CharField(max_length=200,default='',blank=False)
    section_1 = models.CharField(max_length=100,default='') 
    section_2 = models.CharField(max_length=100,default='') 

    def __str__(self):
        return self.test_name

class Person(models.Model):
    tests = models.ManyToManyField(Test)
    title = models.CharField(max_length=3,default="mr",blank=False)
    name = models.CharField(max_length=50,default='',blank=False)
    address = models.CharField(max_length=200,default='',blank=False)
    city = models.CharField(max_length=100,default='',blank=False)

    def __str__(self):
        return self.name

serializers.py
class TestSerializer(serializers.ModelSerializer):
    class Meta:
        model = Test
        fields = ('test_name','section_1','section_2','date_added')

class PersonSerializer(serializers.HyperlinkedModelSerializer):
    tests = TestSerializer(many=True, read_only=True)
    class Meta:
        model = Person
        fields = ('id','title', 'name', 'address', 'city','tests')

numbers.html

{% extends "index.html" %}
{% block names %}
{% for list in send_list %}
    <a href="/"><p>{{list}}</p></a>
{% endfor %}
{% endblock %}

******************************编辑****************** *********

models.py

class City(models.Model):
   city_name=models.CharField(max_length=100,default='',blank=False)

   def __str__(self):
      return self.city_name
class Person(models.Model):
   tests = models.ManyToManyField(Test)
   title = models.CharField(max_length=3,default="mr",blank=False)
   name = models.CharField(max_length=50,default='',blank=False)
   address = models.CharField(max_length=200,default='',blank=False)
   city = models.CharField(max_length=100,default='',blank=False)

views.py

class StudentList(generics.ListCreateAPIView):
    queryset = Person.objects.all()
    serializer_class = PersonSerializer


class CityList(generics.ListCreateAPIView):
    queryset = City.objects.all()
    serializer_class = CitySerializer

class CityDetail(generics.ListCreateAPIView):
    city = City.objects.all()
    serializer_class = CitySerializer

class StudentDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

最佳答案

所以基本上您需要 3 个不同的 API:

  • /cities/ - 为您提供城市列表。
  • /cities/<pk>/students - 为您提供给定城市的学生名单。
  • /students/<pk>/ - 提供 ID 为 pk 的学生的详细信息.

因此,单个 API 无法处理您想要的所有 3 个页面。

您需要 3 个模板 View :

def cities(request):
    data = requests.get('http://127.0.0.1:8000/app/cities/').json()
    context = RequestContext(request, {
        'cities': data.cities,
    })
    return render_to_response('taskmanager/cities.html', context)

def Peoplelist(request, pk):
    data = requests.get('http://127.0.0.1:8000/app/cities/' + pk + '/students/').json()
    context = RequestContext(request, {
        'students': data.students,
    })
    # Better rename this one to students.html
    return render_to_response('taskmanager/numbers.html', context)

def student_details(request, pk):
    data = requests.get('http://127.0.0.1:8000/app/students/' + pk).json()
    context = RequestContext(request, {
        'student': data.student,
    })
    return render_to_response('taskmanager/student_detail.html', context)

为这些 View 配置 url。现在模板应该是这样的:

城市.html:

{% extends "index.html" %}
{% block names %}
{% for city in cities %}
    <a href="{% url 'student_list' city.id %}"><p>{{city.name}}</p></a>
{% endfor %}
{% endblock %}

学生.html:

{% extends "index.html" %}
{% block names %}
{% for student in students %}
    <a href="{% url 'student_detail' student.id %}"><p>{{student.name}}</p></a>
{% endfor %}
{% endblock %}

student_detail.html:

{% extends "index.html" %}
{% block names %}
{{ student.name }}
<table>
    <tr>
    <th>Test Name</th>
    <th>Section 1</th>
    <th>Section 2</th>
    <th>Date Added</th>
    </tr>
{% for test in student.tests %}
    <tr>
        <td>{{ test.test_name }}</td>
        <td>{{ test.section_1 }}</td>
        <td>{{ test.section_2 }}</td>
        <td>{{ test.date_added }}</td>
    </tr>
{% endfor %}
</table>
{% endblock %}

模型修改:

因为你现在有一个 City型号,您可以更改 city字段到 ForeignKeyPerson模型。另外,让我们重命名 PersonStudent :

class Student(models.Model):
   # Removing the tests field. Rather add `student` field in `Test` model
   # tests = models.ManyToManyField(Test)
   title = models.CharField(max_length=3,default="mr",blank=False)
   name = models.CharField(max_length=50,default='',blank=False)
   address = models.CharField(max_length=200,default='',blank=False)
   city = models.ForeignKey(City)

然后更改Test型号:

class Test(models.Model):
    student = models.ForeignKey(Student)
    date_added = models.DateField(default=datetime.datetime.now)
    test_name = models.CharField(max_length=200,default='',blank=False)
    section_1 = models.CharField(max_length=100,default='') 
    section_2 = models.CharField(max_length=100,default='') 

    def __str__(self):
        return self.test_name

对于 View :

  • /cities/ - 为此CityList在您的代码中查看没问题。
  • /cities/<pk>/students/ - 为此,更改您的 StudentList像这样看:

    class StudentList(generics.ListCreateAPIView):
        serializer_class = PersonSerializer
    
        def get_queryset(self):
            city = City.objects.get(pk=self.kwargs.get('pk', None))
            students = Student.objects.filter(city=city)
            return students
    

然后是最后一个:

  • /students/<pk>/ - StudentDetail View 将是这样的:

    class StudentDetail(generics.RetrieveAPIView):
        serializer_class = PersonSerializer
    
        def get_object(self):
            student_id = self.kwargs.get('pk', None)
            return Student.objects.get(pk=student_id)
    

现在对于序列化程序,更改您的 PersonSerializer到这个:

class StudentSerializer(serializers.ModelSerializer):
    test_set = TestSerializer(many=True, required=False)

    class Meta:
        model = Student
        fields = ('id','title', 'name', 'address', 'city', 'test_set')

关于python - 从 django rest 框架中使用 api,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34289460/

相关文章:

python - 使用 Django 将静态文件导入模板

node.js - 重新启动 Node.Js 应用程序时会抛出 EADDRINUSE 错误

python - mac上安装Tensorflow出错

python - NumPy 计算向量的范数 2 的平方

Python 从列表及其变体创建正则表达式

python - settings.pyc 和 __init__.pyc 文件是如何进入我的 Django 应用程序文件夹的?

python - `manage.py runserver` 和 Ctrl+C (Django)

ajax - Django 删除带有确认弹出窗口和多个成功 url 的 CBV

ios - 如何在没有操作队列的情况下取消 GCD 中的请求

java - 在 Linux 上部署 spring boot 应用程序时,日志文件端点出现错误 404