Django API 按唯一 ID 拆分数据
Django API split data by unique ID
我正在制作 Django API。
我使用爬虫程序收集地点和评论数据。
我想按建筑物名称(唯一键)拆分评论数据,但似乎所有评论都保存在一起并传播给所有 URL。
models.py
from django.db import models
import uuid
# Create your models here.
from django.utils.text import slugify
def generate_unique_slug(klass, field):
origin_slug = slugify(field, allow_unicode=True)
unique_slug = origin_slug
numb = 1
while klass.objects.filter(slug=unique_slug).exists():
unique_slug = '%s-%d' % (origin_slug, numb)
numb += 1
return unique_slug
class BuildingData(models.Model):
building_name = models.CharField(max_length=50, unique=True)
slug = models.SlugField(max_length=50, unique=True, allow_unicode=True, default=uuid.uuid1)
building_loc = models.CharField(max_length=50)
building_call = models.CharField(max_length=20)
#building_time = models.CharField(max_length=50)
def save(self, *args, **kwargs):
if self.slug: # edit
if slugify(self.building_name, allow_unicode=True) != self.slug:
self.slug = generate_unique_slug(BuildingData, self.building_name)
else: # create
self.slug = generate_unique_slug(BuildingData, self.building_name)
super(BuildingData, self).save(*args, **kwargs)
class ReviewData(models.Model):
building_name = models.CharField(max_length=50)
review_content = models.TextField()
star_num = models.FloatField()
urls.py
from django.contrib import admin
from django.urls import path
from crawling_data.views import ReviewListAPI
from crawling_data.views import BuildingInfoAPI
urlpatterns = [
path('admin/', admin.site.urls),
path('api/buildingdata/', BuildingInfoAPI.as_view()),
path('api/buildingdata/<str:slug>/', ReviewListAPI.as_view())
]
models.py
# Create your views here.
from django.shortcuts import render
from rest_framework.response import Response
from .models import ReviewData
from .models import BuildingData
from rest_framework.views import APIView
from rest_framework import generics
from rest_framework import permissions
from .serializers import ReviewSerializer
from .serializers import BuildingSerializer
from django.shortcuts import render, get_object_or_404
class BuildingInfoAPI(APIView):
def get(self, request):
queryset = BuildingData.objects.all()
serializer = BuildingSerializer(queryset, many=True)
return Response(serializer.data)
class ReviewListAPI(APIView):
def get(self, request, slug):
queryset = ReviewData.objects.all()
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
爬虫程序的一部分
if __name__=='__main__':
for item in building_dict:
BuildingData(building_name = item['place'], building_loc = item['location'], building_call = item['call']).save()
#BuildingData(building_name = item['place'], building_loc = item['location'], building_call = item['call'], building_time = item['time']).save()
for item in review_dict:
ReviewData(building_name = item['place'], review_content = item['review'], star_num = item['rate']).save()
当程序抓取所有页面时,上面的保存代码运行。
但是此代码将所有评论保存在同一个数据库中。
所以我想要的是这个
URL : api/buildingdata/A/
A building - a review
A building - b review
URL : api/buildingdata/B/
B building - a review
B building - b review
但是我的API看起来像这样
URL : api/buildingdata/A/
A building - a review
A building - b review
B building - a review
B building - b review
URL : api/buildingdata/B/
A building - a review
A building - b review
B building - a review
B building - b review
我应该在哪里解决按建筑物名称拆分评论数据的问题?
这里看起来有两个问题。在您的两个模型之间没有定义 explicit 关系,并且您的 ReviewListAPI 视图正在接受一个 slug,但什么都不做。
您应该在建筑物及其评论之间创建外键关系,然后您可以使用建筑物的 slug it 来过滤仅与该建筑物相关的评论:
您可以像这样更新 ReviewData 模型:
class ReviewData(models.Model):
building = models.ForeignKey(BuildingData, on_delete=models.CASCADE)
...
class ReviewListAPI(APIView):
def get(self, request, slug):
queryset = ReviewData.objects.filter(building__slug=slug)
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
这可能还需要您 update your serializers to reflect the relation between the objects:
如果你不想建立外键关系,你可以在你的视图中尝试这个:
class ReviewListAPI(APIView):
def get(self, request, slug):
building_name = BuildingData.objects.filter(slug=slug).values_list('building_name',flat=True)[0]
queryset = ReviewData.objects.filter(building_name=building_name)
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
在这里,您通过 slug 过滤 BuildingData,return 您要根据其过滤 ReviewData 的单个建筑物名称值
我正在制作 Django API。
我使用爬虫程序收集地点和评论数据。
我想按建筑物名称(唯一键)拆分评论数据,但似乎所有评论都保存在一起并传播给所有 URL。
models.py
from django.db import models
import uuid
# Create your models here.
from django.utils.text import slugify
def generate_unique_slug(klass, field):
origin_slug = slugify(field, allow_unicode=True)
unique_slug = origin_slug
numb = 1
while klass.objects.filter(slug=unique_slug).exists():
unique_slug = '%s-%d' % (origin_slug, numb)
numb += 1
return unique_slug
class BuildingData(models.Model):
building_name = models.CharField(max_length=50, unique=True)
slug = models.SlugField(max_length=50, unique=True, allow_unicode=True, default=uuid.uuid1)
building_loc = models.CharField(max_length=50)
building_call = models.CharField(max_length=20)
#building_time = models.CharField(max_length=50)
def save(self, *args, **kwargs):
if self.slug: # edit
if slugify(self.building_name, allow_unicode=True) != self.slug:
self.slug = generate_unique_slug(BuildingData, self.building_name)
else: # create
self.slug = generate_unique_slug(BuildingData, self.building_name)
super(BuildingData, self).save(*args, **kwargs)
class ReviewData(models.Model):
building_name = models.CharField(max_length=50)
review_content = models.TextField()
star_num = models.FloatField()
urls.py
from django.contrib import admin
from django.urls import path
from crawling_data.views import ReviewListAPI
from crawling_data.views import BuildingInfoAPI
urlpatterns = [
path('admin/', admin.site.urls),
path('api/buildingdata/', BuildingInfoAPI.as_view()),
path('api/buildingdata/<str:slug>/', ReviewListAPI.as_view())
]
models.py
# Create your views here.
from django.shortcuts import render
from rest_framework.response import Response
from .models import ReviewData
from .models import BuildingData
from rest_framework.views import APIView
from rest_framework import generics
from rest_framework import permissions
from .serializers import ReviewSerializer
from .serializers import BuildingSerializer
from django.shortcuts import render, get_object_or_404
class BuildingInfoAPI(APIView):
def get(self, request):
queryset = BuildingData.objects.all()
serializer = BuildingSerializer(queryset, many=True)
return Response(serializer.data)
class ReviewListAPI(APIView):
def get(self, request, slug):
queryset = ReviewData.objects.all()
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
爬虫程序的一部分
if __name__=='__main__':
for item in building_dict:
BuildingData(building_name = item['place'], building_loc = item['location'], building_call = item['call']).save()
#BuildingData(building_name = item['place'], building_loc = item['location'], building_call = item['call'], building_time = item['time']).save()
for item in review_dict:
ReviewData(building_name = item['place'], review_content = item['review'], star_num = item['rate']).save()
当程序抓取所有页面时,上面的保存代码运行。
但是此代码将所有评论保存在同一个数据库中。
所以我想要的是这个
URL : api/buildingdata/A/
A building - a review
A building - b review
URL : api/buildingdata/B/
B building - a review
B building - b review
但是我的API看起来像这样
URL : api/buildingdata/A/
A building - a review
A building - b review
B building - a review
B building - b review
URL : api/buildingdata/B/
A building - a review
A building - b review
B building - a review
B building - b review
我应该在哪里解决按建筑物名称拆分评论数据的问题?
这里看起来有两个问题。在您的两个模型之间没有定义 explicit 关系,并且您的 ReviewListAPI 视图正在接受一个 slug,但什么都不做。
您应该在建筑物及其评论之间创建外键关系,然后您可以使用建筑物的 slug it 来过滤仅与该建筑物相关的评论:
您可以像这样更新 ReviewData 模型:
class ReviewData(models.Model):
building = models.ForeignKey(BuildingData, on_delete=models.CASCADE)
...
class ReviewListAPI(APIView):
def get(self, request, slug):
queryset = ReviewData.objects.filter(building__slug=slug)
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
这可能还需要您 update your serializers to reflect the relation between the objects:
如果你不想建立外键关系,你可以在你的视图中尝试这个:
class ReviewListAPI(APIView):
def get(self, request, slug):
building_name = BuildingData.objects.filter(slug=slug).values_list('building_name',flat=True)[0]
queryset = ReviewData.objects.filter(building_name=building_name)
serializer = ReviewSerializer(queryset, many=True)
return Response(serializer.data)
在这里,您通过 slug 过滤 BuildingData,return 您要根据其过滤 ReviewData 的单个建筑物名称值