Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
197 views
in Technique[技术] by (71.8m points)

python - How to organize a trigram search so that by searching for a relation many-to-many, we get an object that is associated with it in the singular?

I have addresses/models.py:

class Street(models.Model):
    ...
    town = models.ForeignKey(Town, default=None, related_name='streets', on_delete=models.CASCADE, verbose_name='')
    name = models.CharField(max_length=200, db_index=True, verbose_name='',
                            help_text='')
    slug = models.SlugField(max_length=200, db_index=True, verbose_name='')
    is_active = models.BooleanField(default=True, verbose_name='')
    ...

And providers/models.py:

class Provider(models.Model):
    ...
    location = models.ManyToManyField(Street, db_index=True, symmetrical=False, related_name='providers',
                                      verbose_name='')
    name = models.CharField(max_length=200, db_index=True, verbose_name='')
    slug = models.SlugField(max_length=200, db_index=True, verbose_name='')
    is_active = models.BooleanField(default=True, verbose_name='')
    ...

And home/views.py:

def home(request):

    ...
    form = SearchForm()
    query = None
    results = []
    if 'query' in request.GET:
        form = SearchForm(request.GET)
        if form.is_valid():
            query = form.cleaned_data['query']
    
            results = Provider.objects.annotate(
                similarity=TrigramSimilarity('location__name', query),
            ).filter(similarity__gt=0.35).order_by('-similarity')
    
            context = {
                'form': form,
                'query': query,
                'results': results,
            }
    
            return render(request, 'home/home.html', context)
        else:
            return render(request, 'home/search_error.html')
    
    context = {
        'form': form,
        'query': query,
        'results': results,
    }
    
    return render(request, 'home/home.html', context)

At the front home/home.html:

<!-- provider items in results -->
{% for p in results %}
    |it's just here html|
{% endfor %}

As a result (I enter the street name and it finds the correct answer for me, but only lists it as many times as it is mentioned in the request): enter image description here

I want to make it like this: enter image description here

question from:https://stackoverflow.com/questions/65844377/how-to-organize-a-trigram-search-so-that-by-searching-for-a-relation-many-to-man

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

When using postgres in a method call, you can enumerate field names whose values determine the uniqueness of records. If no parameters are specified, then the uniqueness of each record will be determined by the values of all its fields. To display a unique record, use the method distinct():

results = Provider.objects.annotate(
                similarity=TrigramSimilarity('location__name', query),
            ).filter(similarity__gt=0.85).distinct().order_by('-similarity')

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...