我目前正在编写一个应用程序,根据相似的兴趣,他们学习的科目,他们居住的地方等来匹配用户。
我的用户创建/登录系统已编写并正常工作。 但是,我很难开始使用匹配算法。登录该网站后,我希望它能够遍历其他用户'兴趣(这是兴趣模型的多对多字段),然后返回类似用户的列表,与一个或多个兴趣相同或与登录用户在同一课程上的用户。
将这个实现到Django应用程序中的最佳方法是什么?
非常感谢任何帮助和建议!
我附上了我的模型代码片段以供参考。 非常感谢提前
models.py
class Interest(models.Model):
title = models.TextField()
def __unicode__(self):
return self.title
class Location(models.Model):
location = models.CharField(max_length=50)
def __unicode__(self):
return self.location
class Course(models.Model):
title = models.CharField(max_length=40)
faculty = models.CharField(max_length=40)
def __unicode__(self):
return self.title
class MyUser(AbstractBaseUser):
email = models.EmailField(
verbose_name='email address',
max_length=255,
unique=True,
)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
date_of_birth = models.DateField()
course = models.ForeignKey(Course, null=True)
location = models.ForeignKey(Location, null=True)
interests = models.ManyToManyField(Interest, null=True)
bio = models.TextField(blank=True)
objects = MyUserManager()
class MyUserManager(BaseUserManager):
def create_user(self, email, date_of_birth, password=None):
"""
Creates and saves a User with the given email, date of
birth and password.
"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(
email=MyUserManager.normalize_email(email),
date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, date_of_birth, password):
"""
Creates and saves a superuser with the given email, date of
birth and password.
"""
u = self.create_user(email=email,
password=password,
date_of_birth=date_of_birth
)
u.is_admin = True
u.save(using=self._db)
return u
答案 0 :(得分:2)
如果您拥有MyUser
对象mu
,则可以通过mu.interests.all()
获得该用户的所有兴趣。您还可以在查找中使用__in
来测试列表或查询集中的包含。因此,如果您要过滤与我们的MyUser
用户有共同兴趣的所有mu
个对象,您可以执行以下操作:
related_users = MyUser.objects.filter(interests__in=mu.interests.all())
这将生成一个查询集,每个MyUser
对象代表它们所拥有的每个兴趣匹配。例如,如果user1
与mu
有两个共同兴趣,而user2
只有一个共同兴趣,则此过滤器会向我们提供:
[<MyUser: user1>, <MyUser: user1>, <MyUser: user2>]
如果您希望用户只代表一次,无论匹配数量多少,您都可以使用.distinct()
。能够确定匹配的数量可能对您确定“相似性”有用,但您最终会选择定义。
(任何阅读此内容的人都应该对collections
以及其中很酷的内容感兴趣。请阅读此SO帖子了解更多信息:How can I count the occurrences of a list item in Python?)
编辑:你提到你遇到两个错误:
AttributeErrors; "'QuerySet' object has no attribute 'interest'"
您的MyUser
对象具有interest
属性。包含一堆MyUser
个对象的查询集将不具有该属性,但查询集的成员将具有该属性。
例如,使用我们在上面定义的related_users
查询集。由于它是一个查询集,我们可以从.filter()
或.get()
中执行特定对象。我们也可以将其视为列表并访问具有索引位置的单个对象,例如related_users[0]
- 尽管因为它是一个查询集,我们也可以使用特殊的.first()
方法。
但是,我们无法related_users.interests.all()
- 查询集没有interests
属性,查询集中的单个对象 拥有它。如果我们这样做:
>> for user in related_users:
>> print user.interests.all()
然后我们会看到控制台打印查询集中每个用户的所有兴趣,一次一个用户。如果要访问interests
属性,请确保使用单个MyUser
对象而不是整个查询集。
另一个错误:
"'ReverseManyRelatedObjectsDescriptor' object has no attribute 'all'"
您可能正在执行MyUser.interests.all()
之类的操作 - 请记住,MyUser
是您的模型,而不是模型的实例。您需要在.interests.all()
类的单个实例上调用MyUser
,而不是一次调用整个类。换句话说:
>> u = MyUser.objects.get(id=1) #get a single MyUser object
>> u.interests.all()
几乎与另一个问题相同 - 如果要访问interests
属性,请确保使用单个MyUser
对象而不是类定义。
我想知道你是否可以帮助我将其实现到一个视图中?怎么样 我会确保单个MyUser对象是用户吗? 目前登录?
在您的视图中,您可以访问request.user
(或self.request.user
以获取基于类的视图)。那个对象应该是你想要的对象。如果不是,我注意到你正在使用AbstractBaseUser
- 请确保你定义的自定义身份验证模型是否正确配置,否则你会遇到麻烦。
是否有办法显示用户的兴趣所在 通用
对于您的初始用户对象和用户对象,您可以获取related_users
查询集,您可以访问.interests.all()
- 您可以比较视图中的两个列表并确定哪些元素他们有共同点。