Django:m2m关系创建两行而不是一行
我以这种方式扩展了UserModel:Django:m2m关系创建两行而不是一行,django,many-to-many,django-orm,Django,Many To Many,Django Orm,我以这种方式扩展了UserModel: # users/models.py from django.contrib.auth.models import AbstractUser from django.db import models class CustomUser(AbstractUser): # add additional fields in here credit = models.IntegerField(default=200) follow = mod
# users/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
class CustomUser(AbstractUser):
# add additional fields in here
credit = models.IntegerField(default=200)
follow = models.ManyToManyField('self', related_name='follow')
def __str__(self):
return self.username
但我一直在思考如何添加/删除跟随者。我创建了一个具有以下内容的视图:
@login_required
def follow(request, user_id):
user = get_object_or_404(CustomUser, pk=user_id)
if CustomUser.objects.filter(follow=user.pk).exists():
request.user.follow.remove(user)
else:
request.user.follow.add(user)
return redirect('profil', user_id)
问题:
假设request.user.pk为1,user_id为2
对于else中的add部分,我希望数据库中有一行from_customuser_id=1和to_customuser_id=2,但它会创建两行:
按预期,from_customuser_id=1和from_customuser_id=2的一个
一个from_customuser_id=2,from_customuser_id=1,我不需要
对于if中的remove部分,我希望它只删除行
from_customuser_id=1和from_customuser_id=2
但它删除了这两条线
我读了这篇文章,但没有找到解决这个问题的方法
问题:
我应该如何更新我的代码,以使add方法仅插入一行from_customuser_id=1、from_customuser_id=2,以及remove方法仅删除此行(假设当前用户的id为1)
不确定是否相关,但为了完整起见,这是my URL.py的相关部分:
path('follow/<int:user_id>', views.follow, name='follow'),
path('unfollow/<int:user_id>', views.follow, name='unfollow'),
这就是我在模板中对它们的称呼:
{% if follow %}
<a href="{% url 'follow' user_profil.id %}">
Unfollow {{ user_profil.username }}
</a>
{% else %}
<a href="{% url 'unfollow' user_profil.id %}">
Follow {{ user_profil.username }}
</a>
{% endif %}
当你有一个ManyToManyField时,它实际上在两个对象之间创建了一种关系。这也允许您进行反向查找 例如:
class Person(models.Model):
name = model.CharField(max_length=100)
class Pet(models.Model):
owners = models.ManyToMany(Person, related_name="pets")
name = model.CharField(max_length=100)
bob = Person.objects.create(name="Bob")
john = Person.objects.create(name="John")
kitty_kat = Pet.objects.create(name="Kitty Kat")
kitty_kat.owners.set([bob, john])
class Person(models.Model):
name = model.CharField(max_length=100)
followers = models.ManyToManyField('self', related_name='follow')
bob = Person.objects.create(name="Bob")
john = Person.objects.create(name="John")
john.followers.add(bob)
bob.follow.all() # I get john... notice I use follow and not followers
john.followers.all() # I get bob
根据这些模型,一只宠物可以由多人拥有,一个人可以养多只宠物。所以如果我这样做了
bob.pets.all() # I get kitty kat
kitty_kay.owners.all() # I get bob & john
当这个关系应该在同一个模型上时,您最终会创建两个关系。一个是正常的,一个是相反的
例如:
class Person(models.Model):
name = model.CharField(max_length=100)
class Pet(models.Model):
owners = models.ManyToMany(Person, related_name="pets")
name = model.CharField(max_length=100)
bob = Person.objects.create(name="Bob")
john = Person.objects.create(name="John")
kitty_kat = Pet.objects.create(name="Kitty Kat")
kitty_kat.owners.set([bob, john])
class Person(models.Model):
name = model.CharField(max_length=100)
followers = models.ManyToManyField('self', related_name='follow')
bob = Person.objects.create(name="Bob")
john = Person.objects.create(name="John")
john.followers.add(bob)
bob.follow.all() # I get john... notice I use follow and not followers
john.followers.all() # I get bob
为了避免这种情况,可以将symmetric=False传递给字段,并创建一行
followers = models.ManyToManyField('self', related_name='+', symmetrical=False)
将相关的_名称设置为以+开头的任何名称也将防止在本例中不需要的反向查找