python - 如何为 Django Web App 中的每个用户获取唯一的用户数据
问题描述
我正在使用 Django 创建一个 WebApp 作为个人项目。这个应用程序跟踪远足挑战,并使用 API 从天气数据库中获取天气。我目前的问题是创建一个数据库结构,该结构将是一个很好的设计并且将来可以扩展。
目前,我有两个表。(Django 模型)
class Mountain(models.Model):
mnt_name = models.CharField(max_length=100)
latitude = models.FloatField()
longitude = models.FloatField()
elevation = models.IntegerField(default=0)
distance = models.IntegerField(default=0)
users_completed = models.ManyToManyField(User)
# Commented from code to prevent issues
# date_done = models.DateTimeField(blank=True, null=True, default=None)
def __str__(self):
return self.mnt_name
class Challenge(models.Model):
challenge_name = models.CharField(max_length=101)
mountains = models.ManyToManyField(Mountain)
def __str__(self):
return self.challenge_name
我有一些我正在寻找的功能。我可以遍历列表users_completed
并将它们与当前登录的用户进行比较,如果用户在列表中,则更新完成状态。但这不是一个好的解决方案,因为我无法完成用户特定的日期以及其他原因。
直觉上,我认为解决此问题的最佳方法是为每个用户配置文件添加每个挑战的副本,以便用户可以获得特定于用户的数据,例如完成状态和完成日期。但我不确定我将如何去做,或者是否有可能。
关于我应该如何重新排列我的模型的任何建议,以便我可以获得特定于用户的数据,例如山是否已完成,以及完成日期等。
非常感谢所有帮助。谢谢你。
解决方案
我可能会使用双重through
实现。
from django.db import models
from django.contrib.auth.models import User
class Mountain(models.Model):
mnt_name = models.CharField(max_length=100)
latitude = models.FloatField()
longitude = models.FloatField()
elevation = models.IntegerField(default=0)
distance = models.IntegerField(default=0)
class MountainChallenge(models.Model):
"""This allows you to use the same mountain in multiple challenges."""
mountain = models.ForeignKey(Mountain, on_delete=models.CASCADE)
challenge = models.ForeignKey("Challenge", on_delete=models.CASCADE)
users_completed = models.ManyToManyField(User, through="UserMountain")
class UserMountain(models.Model):
"""This associates a user to a MoutainChallenge while storing other data."""
user = models.ForeignKey(User, on_delete=models.CASCADE)
mountain_challenge = models.ForeignKey(MountainChallenge, on_delete=models.CASCADE)
date = models.DateTimeField()
class Challenge(models.Model):
challenge_name = models.CharField(max_length=101)
mountains = models.ManyToManyField(Mountain, through="MountainChallenge")
注意我没有测试过这段代码。
Moutain
您独立于挑战存储对象。- 您有一个
MoutainChallenge
代表 aMountain
作为 a 的一部分Challenge
- 它不能简单
ManyToMany
,因为您要关联已完成山的用户列表 - 这样做
UserMountain
可以保存与成就相关的日期或其他事情 - 在您的应用程序的业务方面,当
UserMountain
实现 a 时,您应该检查当前用户是否已实现当前用户的所有MoutainChallenge
sChallenge
希望这在没有过度设计的情况下是有意义的。
我认为它为未来的扩展留下了空间。
推荐阅读
- git - 如何在我的 PR 中排除他人提交的更改?
- python - 我如何训练一个将 2 张图像拼接/重叠在一起的模型?
- c - 当 strnlen() 使用的最大长度大于实际缓冲区大小时会发生什么?
- c# - 在 ASP.NET ActionResult 中执行 Task.Run() 而不等待结果
- c# - 注册时用Unity设置复杂对象的属性值
- laravel - Laravel DomPDF 无法加载 PDF 文档
- mysql - 在mysql中按同一日期分组
- plugins - 在任何地方手动触发 deoplete 以探索顶级名称
- android - 从文件中获取应用配置
- php - 需要一个允许我将 A 列中的值与 B 列中的值相加的查询