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

时间:2018-08-17 10:17:33

标签: python django

我有一个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字段?这是我通常要添加上下文的步骤

@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字段中(假设传递了相同的上下文名称)?

2 个答案:

答案 0 :(得分:4)

通常最好将它们存储为数组。首先,并非所有数据库都有数组,而且,通常这样做只会带来更多麻烦(高效)查询,尤其是如果数组 refer 其他对象。您通常将多对关系存储在单独的表中。 Django支持此功能: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如何有效地表示这一点,我们可以简单地使用User获得some_context的所有some_context.users.all()。这些对象就是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)

答案 1 :(得分:0)

在这种情况下,您可以采用两种方式使用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)