Reputation: 3038
I have a django model which is basically a group called Contexts
.It contains some fields like name
, description
and a user.Below is the model defined
class Contexts(models.Model):
context_name = models.CharField(max_length=50)
context_description = models.TextField()
users = models.CharField(max_length=255, null=False)
Currently there is only one user per Context
.But I want to add more users to the same Context
.So now I want to change the users
field to an array field.By the way I am using django + postgres.
So this is what I do
class Contexts(models.Model):
context_name = models.CharField(max_length=50)
context_description = models.TextField()
users = ArrayField(ArrayField(models.TextField()))
But then how do I append users to the users
field?This is what I do normally to add a context
@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)
But how do I append one user at a time to the users
field in the same context (assuming same context name is passed)?
Upvotes: 3
Views: 3074
Reputation: 156
In this case you can do two ways either use the postgres json field or go with django ManyToManyField as below,
from django.db import models
from django.contrib.postgres.fields import JSONField
# users field like below
users = JSONField()
or
users = models.ManyToManyField(User)
Upvotes: 0
Reputation: 477684
Usually it is better not to store things as an array. First of all, not all databases have arrays, and furthermore, it usually will only create more trouble to do (efficient) querying, especially if the elements in the array refer to other objects. You usually store many-to-relations in a separate table. Django has support for this: a ManyToManyField
[Django-doc].
Furthermore the code probably already has a problem: you store users
as a CharField
. Now imagine that a user changes their username, then there is no longer a link here. If you want to refer to objects in (another) model, you should use relations, like a ForeignKey
, OneToOneField
, or ManyToManyField
.
So we can probably rewrite it to:
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)
The nice thing is, we no longer need to care about how Django represents this (efficiently), we can simply obtain all the User
s of a some_context
with some_context.users.all()
. Those are then User
objects (or other model objects if you later change the user model).
We can then add a User
to an objects as follows:
@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)
So we can fetch the user, and add it to the field. If you user_request.get('user')
contains the primary key of the user, we can even omit fetching the User
object, and use:
@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)
Upvotes: 3