使用 signals.py 更新模型字段 ( SearchVector )
Update model field ( SearchVector ) using signals.py
我正在尝试使用 post_save 信号更新搜索向量场。
通过“Admin.py”,它运行良好,但通过“表单页面”,searchVector 字段或任何其他字段没有得到更新。
在表单页面中,我有很多字段 - 我通过保存的“标签”
“表格。save_m2m”方法
请查看我的代码并提出建议..
https://dpaste.org/ujPi
提前致谢
#models.py
class JobPostManager(models.Manager):
def search(self, search_text):
search_vectors = (
SearchVector(
'job_title', weight='A', config='english'
)
)
search_query = SearchQuery(
search_text, config='english'
)
search_rank = SearchRank(search_vectors, search_query)
trigram_similarity = TrigramSimilarity(
'job_title', search_text
)
qs = (
self.get_queryset()
.filter(search_vector=search_query)
.annotate(rank=search_rank + trigram_similarity)
.order_by('-rank')
)
return qs
class JobPost(models.Model):
job_title = models.CharField(max_length=100, db_index=True)
job_description = models.TextField()
tags = TaggableManager()
author = models.ForeignKey(User, on_delete=models.CASCADE, db_index=True)
company_name = models.CharField(max_length=100,blank=True,null=True, db_index=True)
objects = JobPostManager()
def __str__(self):
return self.job_title
def get_absolute_url(self):
return reverse('job_post_detail', kwargs={'slug': self.slug, 'pk':self.pk})
####################################################################################
####################################################################################
# views.py
class JobPostCreateView(LoginRequiredMixin, CreateView):
model = JobPost
fields = ['job_title','job_description','tags']
widgets = {
'tags' : forms.TextInput(attrs={'data-role':'tagsinput'}),
}
def get_form(self):
form = super().get_form()
form.fields['tags'].widget = forms.TextInput(attrs={'value': 'all'})
return form
def form_valid(self, form):
print("views - form valid - run ")
newpost = form.save(commit=False)
form.instance.author = self.request.user
form.instance.company_name = self.request.user.company_name
print("form---------------------------")
print(form.instance.author)
print(form.instance.job_title)
print(form.instance.company_name)
print("form end---------------------------")
newpost.save()
print('newpost')
print('--------------------------------',newpost)
print('newpost',newpost.author)
print('newpost',newpost.job_title)
print('Search VECTOR')
print('-------------------')
print(newpost.search_vector)
print('Search VECTOR')
form.save_m2m()
print('save_m2m-----------------------')
print('form-------------',form)
print('form end-------------------')
return super().form_valid(form)
###########################################################################
###########################################################################
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import JobPost
@receiver(post_save, sender=JobPost)
def create_profile(sender, instance, created, **kwargs):
if created:
# JobPost.objects.update(search_vector="instance")
print("i am inside --------------signal")
print(instance.job_title)
print(instance.job_description)
print(instance.tags)
print(instance.company_name)
print(instance.author)
print('Search VECTOR')
print('-------------------')
print(instance.search_vector)
print('Search VECTOR')
print("i am inside signal")
print("i am inside signal")
print("Signal end --------------------------------------")
print("run filter --------------------------------------")
p = JobPost.objects.filter(pk=instance.pk)
print(p)
p2 = JobPost.objects.get(pk=instance.pk).search_vector
print(p2)
print(JobPost.objects.filter(pk=instance.pk)[0].job_title)
print("run filter end--------------------------------------")
p.update(search_vector="instance")
JobPost.objects.filter(pk=instance.pk).update(job_title="Java developer")
print('Search VECTOR after update ')
print('-------------------')
print(instance.search_vector)
print('Search VECTOR')
###########################################################################
############################################################################
## Form HTML
<div class="row">
<div class="col-25">
<label class="fr" for="{{ form.job_title.id_for_label }}">Job title *:</label>
</div>
<div class="col-75">
{{ form.job_title }}
</div>
<div class="invalid-tooltip">
{{ form.job_title.errors }}
</div>
</div>
<div class="row">
<div class="col-25">
<label class="fr" for="{{ form.job_description.id_for_label }}">Job description *:</label>
</div>
<div class="col-75">
{{ form.job_description }}
</div>
<div class="invalid-tooltip">
{{ form.job_description.errors }}
</div>
</div>
#############################################################
为了绝对确定,一切都在完美保存,但您的信号没有被调用,对吗?
这可以通过在 apps.py
文件中添加 2 行代码来解决(它应该与 models.py
文件位于同一深度)。例如,如果应用程序(或包含 models.py
的文件夹)名为“jobs”并且 create_profile
在名为 signals.py
的文件中,您应该像这样修改 apps.py
文件:
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class JobsConfig(AppConfig):
name = 'jobs'
verbose_name = _('Jobs')
# THE FOLLOWING SHOULD BE ADDED.
def ready(self):
from . import signals # noqa
Django 只在需要文件名(如 models.py
、management/commands
等)时“神奇地”找到一些文件,而不是 signals.py
(或文件名create_profile
存在)。片段中的修复不是“漂亮”,但你应该在 ready
方法中进行导入,因为如果在其他地方导入,django 可能会调用 signals.py
两次。
PD。如果这对您有用,如果您在保存时收到“此查询中不允许加入字段引用”错误(我发现此问题的原因)是因为同一模型中的 Django-Taggit + SearchVector 引发此错误,请告诉我
我正在尝试使用 post_save 信号更新搜索向量场。 通过“Admin.py”,它运行良好,但通过“表单页面”,searchVector 字段或任何其他字段没有得到更新。 在表单页面中,我有很多字段 - 我通过保存的“标签” “表格。save_m2m”方法 请查看我的代码并提出建议.. https://dpaste.org/ujPi 提前致谢
#models.py
class JobPostManager(models.Manager):
def search(self, search_text):
search_vectors = (
SearchVector(
'job_title', weight='A', config='english'
)
)
search_query = SearchQuery(
search_text, config='english'
)
search_rank = SearchRank(search_vectors, search_query)
trigram_similarity = TrigramSimilarity(
'job_title', search_text
)
qs = (
self.get_queryset()
.filter(search_vector=search_query)
.annotate(rank=search_rank + trigram_similarity)
.order_by('-rank')
)
return qs
class JobPost(models.Model):
job_title = models.CharField(max_length=100, db_index=True)
job_description = models.TextField()
tags = TaggableManager()
author = models.ForeignKey(User, on_delete=models.CASCADE, db_index=True)
company_name = models.CharField(max_length=100,blank=True,null=True, db_index=True)
objects = JobPostManager()
def __str__(self):
return self.job_title
def get_absolute_url(self):
return reverse('job_post_detail', kwargs={'slug': self.slug, 'pk':self.pk})
####################################################################################
####################################################################################
# views.py
class JobPostCreateView(LoginRequiredMixin, CreateView):
model = JobPost
fields = ['job_title','job_description','tags']
widgets = {
'tags' : forms.TextInput(attrs={'data-role':'tagsinput'}),
}
def get_form(self):
form = super().get_form()
form.fields['tags'].widget = forms.TextInput(attrs={'value': 'all'})
return form
def form_valid(self, form):
print("views - form valid - run ")
newpost = form.save(commit=False)
form.instance.author = self.request.user
form.instance.company_name = self.request.user.company_name
print("form---------------------------")
print(form.instance.author)
print(form.instance.job_title)
print(form.instance.company_name)
print("form end---------------------------")
newpost.save()
print('newpost')
print('--------------------------------',newpost)
print('newpost',newpost.author)
print('newpost',newpost.job_title)
print('Search VECTOR')
print('-------------------')
print(newpost.search_vector)
print('Search VECTOR')
form.save_m2m()
print('save_m2m-----------------------')
print('form-------------',form)
print('form end-------------------')
return super().form_valid(form)
###########################################################################
###########################################################################
from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import JobPost
@receiver(post_save, sender=JobPost)
def create_profile(sender, instance, created, **kwargs):
if created:
# JobPost.objects.update(search_vector="instance")
print("i am inside --------------signal")
print(instance.job_title)
print(instance.job_description)
print(instance.tags)
print(instance.company_name)
print(instance.author)
print('Search VECTOR')
print('-------------------')
print(instance.search_vector)
print('Search VECTOR')
print("i am inside signal")
print("i am inside signal")
print("Signal end --------------------------------------")
print("run filter --------------------------------------")
p = JobPost.objects.filter(pk=instance.pk)
print(p)
p2 = JobPost.objects.get(pk=instance.pk).search_vector
print(p2)
print(JobPost.objects.filter(pk=instance.pk)[0].job_title)
print("run filter end--------------------------------------")
p.update(search_vector="instance")
JobPost.objects.filter(pk=instance.pk).update(job_title="Java developer")
print('Search VECTOR after update ')
print('-------------------')
print(instance.search_vector)
print('Search VECTOR')
###########################################################################
############################################################################
## Form HTML
<div class="row">
<div class="col-25">
<label class="fr" for="{{ form.job_title.id_for_label }}">Job title *:</label>
</div>
<div class="col-75">
{{ form.job_title }}
</div>
<div class="invalid-tooltip">
{{ form.job_title.errors }}
</div>
</div>
<div class="row">
<div class="col-25">
<label class="fr" for="{{ form.job_description.id_for_label }}">Job description *:</label>
</div>
<div class="col-75">
{{ form.job_description }}
</div>
<div class="invalid-tooltip">
{{ form.job_description.errors }}
</div>
</div>
#############################################################
为了绝对确定,一切都在完美保存,但您的信号没有被调用,对吗?
这可以通过在 apps.py
文件中添加 2 行代码来解决(它应该与 models.py
文件位于同一深度)。例如,如果应用程序(或包含 models.py
的文件夹)名为“jobs”并且 create_profile
在名为 signals.py
的文件中,您应该像这样修改 apps.py
文件:
from django.apps import AppConfig
from django.utils.translation import ugettext_lazy as _
class JobsConfig(AppConfig):
name = 'jobs'
verbose_name = _('Jobs')
# THE FOLLOWING SHOULD BE ADDED.
def ready(self):
from . import signals # noqa
Django 只在需要文件名(如 models.py
、management/commands
等)时“神奇地”找到一些文件,而不是 signals.py
(或文件名create_profile
存在)。片段中的修复不是“漂亮”,但你应该在 ready
方法中进行导入,因为如果在其他地方导入,django 可能会调用 signals.py
两次。
PD。如果这对您有用,如果您在保存时收到“此查询中不允许加入字段引用”错误(我发现此问题的原因)是因为同一模型中的 Django-Taggit + SearchVector 引发此错误,请告诉我