使用 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.pymanagement/commands 等)时“神奇地”找到一些文件,而不是 signals.py(或文件名create_profile 存在)。片段中的修复不是“漂亮”,但你应该在 ready 方法中进行导入,因为如果在其他地方导入,django 可能会调用 signals.py 两次。

PD。如果这对您有用,如果您在保存时收到“此查询中不允许加入字段引用”错误(我发现此问题的原因)是因为同一模型中的 Django-Taggit + SearchVector 引发此错误,请告诉我