Duplikaty podczas iteracji po obiektach z danego modelu

Duplikaty podczas iteracji po obiektach z danego modelu
PW
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 17
0

Czołem, mam model Skill który ma relację typu owner z profilem. Czyli każdy zalogowany profil może utworzyć skill. Co jeśli skille od róznych profili mają tą samą nazwę (ale zawartość jest inna)? Dodam, że wyrażenia Q i distinct działają wyśmienicie przy "search barze" z pliku utils - eliminują całkowite duplikaty obiektu podczas iteracji. Jak uniknąć dublowania tych obiektów które mają tylko tą samą nazwę? Próbowałem z: skills.values('name').distinct() ale dostaję błąd,że baza SQL nie obsługuje tego a Postgre tak.

zawartość views.py

Kopiuj
def skills(request):
    skills, search_query = searchSkills(request) # function searchSkills in utils.py
    #unique_skills = skills.values('name').distinct().annotate(id=F('pk'))

    context = {'skills': skills,'search_query':search_query,}
    return render(request, 'dentists/skills.html', context)

oraz zawartość models.py:

Kopiuj
class Skill(models.Model):
    owner = models.ForeignKey(Profile, null=True, blank=True,on_delete=models.CASCADE)
    name = models.CharField(max_length=200, blank=True, null=True)

zawartość utlis.py:

Kopiuj
def searchSkills(request):
    search_query = ''

    if request.GET.get('search_query'):
        search_query = request.GET.get('search_query')

    skills = Skill.objects.distinct().filter(
        Q(name__icontains=search_query) |
        Q(description__icontains=search_query) |
        Q(owner__name__icontains=search_query) |
        Q(tags__in=tags)

    )
    return skills,search_query

pętla w szablonie: {% for skill in skills %}. Czy jest jakiś prosty sposób na wymienienie wszystkich skilli wszystkich profili ale bez powtórzeń ze względu na nazwę?

AN
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 989
0

Możesz po prostu przefiltrować duplikaty za pomocą pythona (np. set)

PW
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 17
0

Spróbowałem z:

Kopiuj
wszystkie_obiekty = Skill.objects.all()
results = {wszystkie_obiekty}

i zawartość pętli z szablonu (pomijając kolumny z html i css etc dla ułatwienia:

Kopiuj
{% for skill in  results %}                                                 
    <h3>{{ skill.name }}</h3>
    <h5>Created on: {{ skill.created}}</h5>

    {{skill.description|slice:'190'}}

<a href="{% url 'single-skill' skill.id %}"> click for more info's  about this skill >>> </a></p>

{% endfor %}

dostaję błąd: NoReverseMatch at / wskazuje na link: href="{% url 'single-skill' skill.id %}. Czy po zrobieniu seta można będzie się odwołać do poszczególnego id skilla?

CP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 70
1

O matko, korzystałeś kiedyś z dokumentacji i debuggera?

.objects.all() zwraca ci QuerySet i to jest pojedynczy obiekt i go wkładasz do seta otrzymując seta z pojedynczym obiektem QuerySet.
Za pomocą asterixamożesz zawsze użyć wypakowania, powinno działać na tym obiekcie QuerySet, chyba, że nikt tej opcji nie zaprojektował, ale raczej jest, tablice i mapy tak się rozpakowuje w pythonie itp.

Możesz takie rzeczy sobie podglądnąć pod debuggerem pythona i obserwować czy to co robisz ma sens.

Jako że to jest ORM w django, to klasa ma instrukcje tłumaczone na sql query danej bazy danych i włączenie sobie connection.force_debug_cursor = True pozwoli ci obserwować SQL zapytania do bazy, przydaje się przy debugowaniu.

Twój problem to jest jak dobrze zrozumiałem masz Wiele tych samych skillów, ale coś innego się w nich różni, jak zrobisz set na nich to jest sprawdzany hash prawdopodobnie, możesz nadpisać tą funkcję żeby była liczona tylko dla id skilla.
Ale jak ją napisałeś na filter i innych, które robią na sql queries to to nie będzie wykonane na poziomie pythona, ale na poziome bazy sql.

Możesz też sobie ten obiekt rozpakować i samemu ręcznie w pythonie odfiltriować będzie to wolniejsze i bez cachowania, bo te opcje zapewnia baza.

Też za dobrze nie zrozumiałem pytania, bo jak nie zależy ci na duplikatach to po prostu każdą znalezionego skilla po prostu raz wyświetlasz, a jak jest unikalny to musisz sprawdzić, co twoja operacja sprawdza za wartości unikalności czy hash całego wiersza.

PW
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 17
0

Też za dobrze nie zrozumiałem pytania, bo jak nie zależy ci na duplikatach to po prostu każdą znalezionego skilla po prostu raz wyświetlasz.

Właśnie o to mi chodzi, jak to wyświetlić.
Dziękuję za odpowiedź, rzeczywiście mam małe doświadczenie z debuggerem w django. Dopiero się uczę. Od czego zacząć?

CP
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 70
0

Masz w pythonie funkcje breakpoint() w krytycznych sytuacjach wywołaj ją i miej dobry code edytor co ci obsłuży, a jak nie naucz się konsolowego.
import pdb, ma też pewne opcje debuggera.

Program ci się zatrzymuje tam gdzie chcesz, sprawdzasz co jest w zmiennych i potem idziesz linijkę dwie, czy do przodu, patrzysz co się za funkcje wykonały i jak zmieniło się wszystko

Analizujesz próbujesz wywnioskować co źle zrobiłeś czemu program tak się zachował, czasem we frameworku lub zawsze jest coś niezrozumiałego.

Ja używam breakpoint, ale można w edytorze nacisnąć f3 chyba.

PW
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 17
0

@ChłopPrzyszłyRycerz dziękuję za odpowiedź, zbadam breakpoint.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.