我有一个Django模型,基本上是一个名为Contexts
的组。它包含一些字段,例如name
,description
和一个用户。下面是定义的模型
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
字段中(假设传递了相同的上下文名称)?
答案 0 :(得分:4)
通常最好将它们存储为数组。首先,并非所有数据库都有数组,而且,通常这样做只会带来更多麻烦(高效)查询,尤其是如果数组 refer 其他对象。您通常将多对关系存储在单独的表中。 Django支持此功能:ManyToManyField
[Django-doc]。
此外,代码可能已经 有问题:您将users
存储为CharField
。现在,假设用户更改了用户名,那么这里不再有链接。如果要在(另一个)模型中引用对象,则应使用诸如ForeignKey
,OneToOneField
或ManyToManyField
之类的关系。
因此我们可以将其重写为:
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)