如何在django中存储用户数组?

jv4diomz  于 2023-04-13  发布在  Go
关注(0)|答案(2)|浏览(217)

我有一个Django模型,基本上是一个名为Contexts的组。它包含一些字段,如namedescription和一个用户。下面是定义的模型

class Contexts(models.Model):
    context_name = models.CharField(max_length=50)
    context_description = models.TextField()
    users = models.CharField(max_length=255, null=False)

目前每个Context只有一个用户。但是我想添加更多的用户到同一个Context。所以现在我想将users字段更改为数组字段。顺便说一下,我使用django + postgres。
所以这就是我的工作

class Contexts(models.Model):
    context_name = models.CharField(max_length=50)
    context_description = models.TextField()
    users = ArrayField(ArrayField(models.TextField()))

但是如何将users追加到users字段呢?

@csrf_exempt
def context_operation(request):
    user_request = json.loads(request.body.decode('utf-8'))
    if request.method == "POST":
        try:
            if user_request.get("action") == "add":
                print("add")
                conv = Contexts.objects.create(
                    context_name=user_request.get("context_name"),
                    context_description=user_request.get("context_description"),
                    users=user_request.get("user")
                )

        except Exception as e:
            print("Context saving exception", e)
            return HttpResponse(0)
        return HttpResponse(1)

但是如何在同一个上下文中一次将一个用户追加到users字段中(假设传递了相同的上下文名称)?

hvvq6cgz

hvvq6cgz1#

通常情况下,最好不要将数据存储为数组。首先,并不是所有的数据库都有数组,而且,它通常只会给(高效)查询带来更多麻烦,特别是当数组中的元素引用其他对象时。你通常将多个to关系存储在一个单独的表中。Django支持这一点:a**ManyToManyField**[Django-doc].
此外,代码可能已经有了一个问题:你将users存储为CharField。现在假设用户更改了他们的用户名,那么这里就不再有链接了。如果你想引用(另一个)模型中的对象,你应该使用关系,比如ForeignKeyOneToOneFieldManyToManyField
所以我们可以把它改写为:

from django.db import models
from django.conf import settings

class Contexts(models.Model):
    context_name = models.CharField(max_length=50)
    context_description = models.TextField()
    users = ManyToManyField(settings.AUTH_USER_MODEL)

好的一面是,我们不再需要关心Django如何(有效地)表示这一点,我们可以简单地用some_context.users.all()获得some_context的所有User。这些就是User对象(或者其他模型对象,如果你稍后更改用户模型)。
然后我们可以将User添加到对象中,如下所示:

@csrf_exempt
def context_operation(request):
    user_request = json.loads(request.body.decode('utf-8'))
    if request.method == "POST":
        try:
            if user_request.get("action") == "add":
                print("add")
                conv = Contexts.objects.create(
                    context_name=user_request.get("context_name"),
                    context_description=user_request.get("context_description"),
                )
                my_user = User.objects.get(username=user_request.get("user"))
                conv.users.add(my_user)

        except Exception as e:
            print("Context saving exception", e)
            return HttpResponse(0)
        return HttpResponse(1)

所以我们可以获取用户,并将其添加到字段中。如果user_request.get('user')包含用户的 * 主键 *,我们甚至可以省略获取User对象,并用途:

@csrf_exempt
def context_operation(request):
    user_request = json.loads(request.body.decode('utf-8'))
    if request.method == "POST":
        try:
            if user_request.get("action") == "add":
                print("add")
                conv = Contexts.objects.create(
                    context_name=user_request.get("context_name"),
                    context_description=user_request.get("context_description"),
                )
                # if user_request.get('user') contains the *primary* key of the User model
                conv.users.add(user_request.get("user"))

        except Exception as e:
            print("Context saving exception", e)
            return HttpResponse(0)
        return HttpResponse(1)
bwitn5fc

bwitn5fc2#

在这种情况下,你可以使用两种方法,要么使用postgres json字段,要么使用django ManyToManyField,如下所示:

from django.db import models
from django.contrib.postgres.fields import JSONField

# users field like below

users = JSONField()

or

users = models.ManyToManyField(User)

相关问题