Как я могу вызвать функцию класса, которая вставляет строку в базу данных, из моего шаблона django?
Привет, я ноб и я делаю instagram followers scraper на Django.
Я делаю функцию, которая должна добавить 1 (только 1, потому что она работает очень медленно) нового последователя в db, который берется из уже работающих функций ssraping и помещается в класс.
class ListOfFollowers(ListView):
model = Followers
context_object_name = 'followers_of'
template_name = 'insta/followers.html'
def get_follower(self, username):
loader = instaloader.Instaloader()
loader.login('***', '***')
profile = instaloader.Profile.from_username(loader.context, username)
followers = profile.get_followers()
followers_tuple = tuple(followers)
i = random.randint(0, len(followers_tuple) - 1)
login = followers_tuple[i].username
photo = followers_tuple[i].get_profile_pic_url()
url = f'https://www.instagram.com/{login}/'
mutual_subscription = followers_tuple[i] in profile.get_followees()
res = {'login': login, 'photo': photo, 'url': url, 'mutual_subscription': mutual_subscription}
return res
def add_followers(self):
username = WhoFollow.objects.get(follow_on__contains=self.kwargs['follow_id']).title
context = None
while not context:
try:
context = get_follower(username)
except:
next
context.update({'follow_on': self.kwargs['follow_id']})
res = Followers(context)
res.save()
def get_queryset(self):
return Followers.objects.filter(follow_on=self.kwargs['follow_id'])
функция вызывает add_followers (блок попыток просто потому, что он не всегда работает с первой попытки)
Мои модели
class WhoFollow(models.Model):
title = models.CharField(max_length=255)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('follow', kwargs={'follow_id': self.pk})
class Followers(models.Model):
login = models.CharField(max_length=255)
photo = models.ImageField(upload_to="photos/", blank=True)
url = models.URLField()
mutual_subscription = models.BooleanField(default=False)
time_add = models.DateTimeField(auto_now_add=True)
time_unfollow = models.DateTimeField(blank=True)
follow_on = models.ForeignKey(WhoFollow, on_delete=models.PROTECT)
def __str__(self):
return self.login
И мой шаблон
{% extends 'insta/Base.html' %}
{% block content %}
<h1>Who we find</h1>
<ul>
{% for l in object_list %}
<li>
<h5>{{l.login}}</h5>
</li>
{% endfor %}
</ul>
<!-- from there i dont understand what i should do too -->
<form action="{% url views.ListOfFollowers.}">
<button type="submit" onclick="">add another 1</button>
</form>
{% endblock %}
Простите за слишком много кода, но моя голова уже сломана над этой задачей.
Есть некоторые проблемы с вашим кодом:
Во-первых, вы добавили два метода get_follower() и add_followers() к вашему ListView, но неясно, как (если вообще) они вызываются. Мне кажется, что вы, возможно, неправильно понимаете концепцию ListView. Цель ListView - отобразить список объектов, а не добавить что-то. Поэтому вместо этого вы хотите создать новое представление для добавления последователей. Вы можете просто определить простую функцию представления для этого, не обязательно CBV.
Во-вторых, для каждого представления должен быть определен свой URL. Вы не указали свой urls.py, но я предполагаю, что {% url views.ListOfFollowers.} в шаблоне не будет работать. Вместо этого вам нужно определить имя URL в вашем urls.py (по одному для каждого представления) и указать его в вашем шаблоне.
Я совершенно неправильно понял концепцию CBV.
Ответ заключается в том, что я должен сделать это внутри CreateVeiw после валидации формы, где я выбираю, какой логин использовать.
Есть результат:
class AddFollowers(CreateView):
form_class = AddFollower
model = Followers
template_name = 'insta/add_follower.html'
def get_success_url(self):
return reverse_lazy('home')
def form_valid(self, form):
# Here is a body of scraping script where i creating a list of objects to add in db
Followers.objects.bulk_create(objs=res)
return HttpResponseRedirect(f'http://127.0.0.1:8000/)