簡體   English   中英

從Django Rest框架消費API

[英]Consuming api from 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個模板視圖:

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)

配置這些視圖的URL。 現在,模板將像:

city.html:

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

students.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字段更改為“ ForeignKey Person模型。 另外,讓我們將Person重命名為Student

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

對於視圖:

  • /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視圖如下:

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

如果我正確理解,則希望在api響應中為學生提供超鏈接 為此,在serializer.py中添加以下內容

class StudentByCityField(serializers.RelatedField):
    def to_representation(self, city):
        student_list = self.objects.filter(city=city)
        link_list = list()
        append_link = link_list.append
        for student in student_list:
            append_link("/app/students/%s" % student.name)
        return link_list

class PersonByCitySerializer(serializers.ModelSerializer):
    city_name = StudentByCityField(source='city', read_only=True)
    class Meta:
        model = Test
        fields = ('city_name',)

但是,如果您想做此HTML方面,這將是微不足道的

  1. views.py
def get_cities(request):
    pesrons = Person.objects.all()
    pesrons.query.group_by = ['city']
    city_set = set([i.city for i in persons])
    context = RequestContext(request, {
        'city_list': list(city_set),
    })
    return render_to_response('cities.html', context)

def get_students_by_city(request, city):
    student_list = Person.objects.filter(city=city)
    context = RequestContext(request, {
        'students': student_list,
    })
    # Better rename this one to students.html
    return render_to_response('students_by_city.html', context)

def get_student_details(request, id):
    student = Person.objects.get(id=id)
    context = RequestContext(request, {
        'student': student,
    })
    return render_to_response('student_detail.html', context)
  1. 范本

city.html

    {% extends "index.html" %}
    {% block names %}
    <ul>
    {% for city in city_list %}
        <li><a href="{% url 'student_by_city' city.name %}">
        {{city.name}}
        </a></li>
    {% endfor %}
    </ul>
    {% endblock %}

students_by_city.html

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

student_detail.html

{% extends "index.html" %}
{% block names %}

   <!-- Display here your data as you like -->

{% endblock %}
  1. urls.py
urlpatterns = patterns('',

    url(r'^app/cities/$', views.get_cities, name="participant-register"), 
    url(r'^app/students/(?P<id>\d+)$', views.get_student_by_city, name="student_by_city"),
    url(r'^app/student/(?P<city>\w+/$', views.get_student_detail, name="student_detail"),                       
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM