【问题标题】:How do you get unique user data for each user in a Django Web App如何为 Django Web App 中的每个用户获取唯一的用户数据
【发布时间】:2020-08-17 01:37:51
【问题描述】:

我正在使用 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 的列表并将它们与当前登录的用户进行比较,如果用户在列表中,则更新完成状态。但这不是一个好的解决方案,因为我无法完成用户特定的日期以及其他原因。

凭直觉,我认为解决此问题的最佳方法是为每个用户个人资料添加每个挑战的副本,以便用户可以获得特定于用户的数据,例如完成状态和完成日期。但我不确定我将如何去做,或者是否有可能。

关于我应该如何重新排列我的模型的任何建议,以便我可以获得用户特定的数据,例如山是否已完成,以及完成日期等。

非常感谢所有帮助。谢谢。

【问题讨论】:

  • 用户完成挑战还是用户完成山脉?挑战有多座山吗?
  • @Mike67 用户完成了山脉。当所有山脉都完成后,挑战将被视为完成。挑战确实有多座山。
  • 使用中间模型
  • @FranciscoCouzo 那么将用户特定的字段分解到单独的模型中并将用户添加到模型中?

标签: python sql django database


【解决方案1】:

为此,您可以使用第三个表将用户映射到山\挑战。

Achievement:
   AchievementID
   UserID
   MountainID      -- set when mountain completed
   ChallengeID     -- set when full challenge completed
   AchievementDate

当用户完成一座山或一个完整的挑战时,会创建一个条目。

【讨论】:

    【解决方案2】:

    我可能会使用双 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,它代表Mountain 作为Challenge 的一部分
    • 不能是简单的ManyToMany,因为您要关联已完成山的用户列表
    • 这是使用 UserMountain 完成的,它可以保存与成就相关的日期或其他内容
    • 在应用的业务方面,当达到UserMountain 时,您应该检查当前用户是否已达到所有当前ChallengeMoutainChallenges

    希望这在没有过度设计的情况下有意义。

    我认为它为未来的扩展留下了空间。

    【讨论】:

    • 我决定采用之前的响应,因为它不那么复杂并且适合我的项目需求。我确实喜欢您对模型的设计,如果我决定让 Web 应用程序更加复杂或实际向公众提供,它可能会在未来实现。不过感谢您的回复!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-24
    • 1970-01-01
    • 2020-06-09
    • 2018-02-06
    • 2015-07-29
    • 1970-01-01
    • 2023-01-11
    相关资源
    最近更新 更多