django rest 框架使用动作装饰器添加路径以查看 url 中的财务报表
django rest framework using action decorator to add path to view financial statement in url
我需要以下 URLs 才能工作,其中 ticker 代表股票代码,例如 AAPL 或 AMZN,而 is 代表 income_statement。
localhost:8000/stocks/
localhost:8000/stocks/<TICKER>/
localhost:8000/stocks/<TICKER>/is/
在下面的 views.py 文件中,我使用了一个视图集,它和路由器自动配置上面的前两个 url,而对于第三个 url,我正在使用操作methods=['get']
和 url_path="is"
装饰器实现 localhost:8000/stocks/<TICKER>/is/
路径。
第三个URL已配置,但在浏览器中输入以下url时出现ticker
键错误:localhost:8000/stocks/AAPL/is/
我在这里做错了什么,我认为错误在 views.py
get_income_statement
函数中?
models.py
class Stock(models.Model):
id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
ticker = models.CharField(max_length=10, unique=True, primary_key=True)
slug = models.SlugField(default="", editable=False)
def save(self, *args, **kwargs):
value = self.ticker
self.slug = slugify(value, allow_unicode=True)
super().save(*args, **kwargs)
def __str__(self):
return self.ticker
class Meta:
verbose_name = "stock"
verbose_name_plural = "stocks"
ordering = ["ticker"]
class IncomeStatement(models.Model):
ticker = models.ForeignKey(
Stock, on_delete=models.CASCADE, related_name="income_statements"
)
date = models.DateField(default=datetime.date.today)
PERIODICITY_CHOICES = [("ANNUAL", "ANNUAL"), ("QUARTERLY", "QUARTERLY")]
periodicity = models.CharField(
max_length=10, choices=PERIODICITY_CHOICES, default="annually"
)
net_income_continuous_operations = models.DecimalField(
max_digits=20, decimal_places=2
views.py
class StockViewSet(viewsets.ModelViewSet):
queryset = Stock.objects.all()
serializer_class = StockSerializer
# lookup_field = "slug"
@action(detail=True, methods=["get"], url_path="is", url_name="is")
def get_income_statement(self, request, *args, **kwargs):
income_statement = self.queryset.get(ticker=kwargs["ticker"]).select_related(
"income_statements"
)
serializer = IncomeStatementSerializer(data=income_statement)
if serializer.is_valid():
return Response(serializer.data)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
urls.py
router = DefaultRouter()
router.register(r"stocks", views.StockViewSet)
urlpatterns = router.urls
设置lookup_field = "ticker"
class StockViewSet(viewsets.ModelViewSet):
# rest of your code
<b>lookup_field = "ticker"</b>
更新-1
class StockViewSet(viewsets.ModelViewSet):
queryset = Stock.objects.all()
serializer_class = StockSerializer
<b>lookup_field = "ticker"</b>
@action(detail=True, methods=["get"], url_path="is", url_name="is")
def get_income_statement(self, request, *args, **kwargs):
<b>is_qs = IncomeStatement.objects.filter(ticker=self.get_object())
serializer = IncomeStatementSerializer(is_qs, many=True)</b>
return Response(serializer.data)
我需要以下 URLs 才能工作,其中 ticker 代表股票代码,例如 AAPL 或 AMZN,而 is 代表 income_statement。
localhost:8000/stocks/
localhost:8000/stocks/<TICKER>/
localhost:8000/stocks/<TICKER>/is/
在下面的 views.py 文件中,我使用了一个视图集,它和路由器自动配置上面的前两个 url,而对于第三个 url,我正在使用操作methods=['get']
和 url_path="is"
装饰器实现 localhost:8000/stocks/<TICKER>/is/
路径。
第三个URL已配置,但在浏览器中输入以下url时出现ticker
键错误:localhost:8000/stocks/AAPL/is/
我在这里做错了什么,我认为错误在 views.py
get_income_statement
函数中?
models.py
class Stock(models.Model):
id = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
ticker = models.CharField(max_length=10, unique=True, primary_key=True)
slug = models.SlugField(default="", editable=False)
def save(self, *args, **kwargs):
value = self.ticker
self.slug = slugify(value, allow_unicode=True)
super().save(*args, **kwargs)
def __str__(self):
return self.ticker
class Meta:
verbose_name = "stock"
verbose_name_plural = "stocks"
ordering = ["ticker"]
class IncomeStatement(models.Model):
ticker = models.ForeignKey(
Stock, on_delete=models.CASCADE, related_name="income_statements"
)
date = models.DateField(default=datetime.date.today)
PERIODICITY_CHOICES = [("ANNUAL", "ANNUAL"), ("QUARTERLY", "QUARTERLY")]
periodicity = models.CharField(
max_length=10, choices=PERIODICITY_CHOICES, default="annually"
)
net_income_continuous_operations = models.DecimalField(
max_digits=20, decimal_places=2
views.py
class StockViewSet(viewsets.ModelViewSet):
queryset = Stock.objects.all()
serializer_class = StockSerializer
# lookup_field = "slug"
@action(detail=True, methods=["get"], url_path="is", url_name="is")
def get_income_statement(self, request, *args, **kwargs):
income_statement = self.queryset.get(ticker=kwargs["ticker"]).select_related(
"income_statements"
)
serializer = IncomeStatementSerializer(data=income_statement)
if serializer.is_valid():
return Response(serializer.data)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
urls.py
router = DefaultRouter()
router.register(r"stocks", views.StockViewSet)
urlpatterns = router.urls
设置lookup_field = "ticker"
class StockViewSet(viewsets.ModelViewSet):
# rest of your code
<b>lookup_field = "ticker"</b>
更新-1
class StockViewSet(viewsets.ModelViewSet):
queryset = Stock.objects.all()
serializer_class = StockSerializer
<b>lookup_field = "ticker"</b>
@action(detail=True, methods=["get"], url_path="is", url_name="is")
def get_income_statement(self, request, *args, **kwargs):
<b>is_qs = IncomeStatement.objects.filter(ticker=self.get_object())
serializer = IncomeStatementSerializer(is_qs, many=True)</b>
return Response(serializer.data)