我使用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 %}
********* EDIT **************** *********
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
答案 0 :(得分:3)
所以基本上你需要3种不同的API:
/cities/
- 为您提供城市列表。/cities/<pk>/students
- 提供给定城市的学生名单。/students/<pk>/
- 提供身份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)
配置这些视图的网址。现在模板就像:
{% extends "index.html" %}
{% block names %}
{% for city in cities %}
<a href="{% url 'student_list' city.id %}"><p>{{city.name}}</p></a>
{% endfor %}
{% endblock %}
{% extends "index.html" %}
{% block names %}
{% for student in students %}
<a href="{% url 'student_detail' student.id %}"><p>{{student.name}}</p></a>
{% endfor %}
{% endblock %}
{% 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
更改为此<:p>
class StudentSerializer(serializers.ModelSerializer):
test_set = TestSerializer(many=True, required=False)
class Meta:
model = Student
fields = ('id','title', 'name', 'address', 'city', 'test_set')
答案 1 :(得分:1)
如果我正确理解,您希望为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方面,这将是微不足道的
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)
<强> cities.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 %}
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"),
)