You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:如何在Django中实现SQLite的auth_user与自定义输入表关联查询

Hey there! 我完全懂你现在的处境——大学项目卡关真的让人头大,别慌,咱们一步步把这个Django关联查询的问题搞定。

首先,咱们得先把模型的关系理清楚,因为Django的ORM是围绕模型关联来做的。假设你自己创建的输入表叫WaistRecord(用来存腰围数据的),你需要在这个模型里加一个外键关联Django自带的auth_user表,这样ORM才能知道两张表怎么关联。

第一步:完善模型关联

打开你的models.py,修改你的输入表模型,加上外键字段:

from django.db import models
from django.contrib.auth.models import User

class WaistRecord(models.Model):
    # 关联auth_user表,on_delete=models.CASCADE表示如果用户被删除,对应的腰围数据也跟着删
    # related_name是给反向查询用的,方便从User对象找到对应的腰围记录
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='waist_records')
    waist_size = models.FloatField(verbose_name="腰围")  # 你的腰围字段,类型根据实际调整
    created_at = models.DateTimeField(auto_now_add=True, verbose_name="记录时间")  # 可选,用来记录数据录入时间

    def __str__(self):
        return f"{self.user.username} - {self.waist_size}cm"

如果这个表之前已经创建了(也就是你已经执行过migrate),那现在需要更新数据库:

python manage.py makemigrations
python manage.py migrate

注意:如果你的表已经有数据,migrate的时候可能会提示你给user字段设置默认值,你可以暂时设为1(对应admin用户),之后再手动把数据关联到正确的用户上。

第二步:实现关联查询

现在模型关联好了,就可以用Django的ORM来实现你要的查询逻辑了,分两种常见场景:

场景1:查询单个用户的所有腰围数据

比如你要获取当前登录用户的腰围记录,可以这么写:

# 在你的views.py里
from django.contrib.auth.decorators import login_required
from django.shortcuts import render
from .models import WaistRecord

@login_required  # 确保用户登录才能访问
def user_waist_list(request):
    # 方法一:用反向查询(因为模型里设置了related_name='waist_records')
    waist_records = request.user.waist_records.all()
    # 方法二:正向查询,效果一样
    # waist_records = WaistRecord.objects.filter(user=request.user)
    return render(request, 'waist_list.html', {'records': waist_records})

然后在模板waist_list.html里展示数据:

{% for record in records %}
    <div>
        <span>用户名:{{ record.user.username }}</span>
        <span>腰围:{{ record.waist_size }}cm</span>
        <span>记录时间:{{ record.created_at|date:"Y-m-d H:i" }}</span>
    </div>
{% empty %}
    <p>还没有录入腰围数据哦</p>
{% endfor %}

场景2:查询所有用户及其对应的腰围数据(比如每个用户最新的一条)

如果你要像SQL那样,把每个用户和他们的腰围数据关联起来(比如只取每个用户最新的一条),可以用annotate和Subquery来实现:

from django.contrib.auth.models import User
from django.db.models import Max, Subquery, OuterRef
from .models import WaistRecord

# 获取每个有腰围数据的用户,以及他们最新的腰围记录
latest_waist = WaistRecord.objects.filter(user=OuterRef('pk')).order_by('-created_at')
users_with_waist = User.objects.annotate(
    latest_waist_size=Subquery(latest_waist.values('waist_size')[:1]),
    latest_record_time=Subquery(latest_waist.values('created_at')[:1])
).filter(latest_waist_size__isnull=False)

这样users_with_waist里的每个User对象就多了latest_waist_size和latest_record_time两个属性,直接用就行。

如果你已经有SQL语句,怎么对应到ORM?

假设你的SQL语句是这样的:

SELECT auth_user.username, waist_record.waist_size 
FROM auth_user 
JOIN waist_record ON auth_user.id = waist_record.user_id;

对应的Django ORM查询就是:

combined_data = WaistRecord.objects.select_related('user').values(
    'user__username', 
    'waist_size', 
    'user__id'
)

select_related('user')是用来优化查询的,避免多次查询数据库(也就是解决N+1问题),values()用来指定你要获取的字段,返回的是一个字典列表。

最后补个小提醒

如果你的旧数据还没关联到用户,你可以用Django的shell来批量处理:

python manage.py shell

然后在shell里执行:

from django.contrib.auth.models import User
from .models import WaistRecord

# 假设你的WaistRecord里有个username字段对应auth_user的用户名,批量关联
for record in WaistRecord.objects.all():
    user = User.objects.filter(username=record.username).first()
    if user:
        record.user = user
        record.save()

放心,按照这个步骤来,你肯定能搞定这个关联查询的,加油!

内容的提问来源于stack exchange,提问作者J.Kidd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 09:58:37