beatonma / django-wm

Automatic Webmention functionality for Django models
https://beatonma.org/webmentions_tester/
GNU General Public License v3.0
13 stars 2 forks source link

RuntimeError for incoming webmentions #7

Closed rasulkireev closed 4 years ago

rasulkireev commented 4 years ago

I was able to go through the whole process of setting up the Celery worker, Redis database, and all the settings for the django-wm. I am running the celery worker on my Ubuntu 18.04 droplet and when I am testing the incoming submission I get the following error:

[2020-01-16 23:31:12,680: ERROR/ForkPoolWorker-1] Task mentions.tasks.incoming_webmentions.process_incoming_webmention[7edc74b1-8e2a-4111-b8cf-3d0c963f9250] raised unexpected: RuntimeError("Model class django.contrib.flatpages.models.FlatPage doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.",)
Traceback (most recent call last):
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/celery/app/trace.py", line 385, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/celery/app/trace.py", line 650, in __protected_call__
    return self.run(*args, **kwargs)
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/mentions/tasks/incoming_webmentions.py", line 42, in process_incoming_webmention
    obj = _get_target_object(target)
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/mentions/tasks/incoming_webmentions.py", line 111, in _get_target_object
    return get_model_for_url_path(path)
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/mentions/util.py", line 24, in get_model_for_url_path
    from django.contrib.flatpages.views import flatpage
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/django/contrib/flatpages/views.py", line 2, in <module>
    from django.contrib.flatpages.models import FlatPage
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/django/contrib/flatpages/models.py", line 8, in <module>
    class FlatPage(models.Model):
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/django/db/models/base.py", line 111, in __new__
    "INSTALLED_APPS." % (module, name)
RuntimeError: Model class django.contrib.flatpages.models.FlatPage doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.

I figured the error is due to the lack of django.contrib.flatpages in my INSTALLED_APPS. I followed [this instruction]() to enable it, but that did not help unfortunately.

Would you happen to know what is the issue? Thanks a ton in advance.

rasulkireev commented 4 years ago

After a bunch of tweaking, I resolved the issue, but unfortunately, not fully.

I still get the RunTime error, but this time it is more hopeful and I hoped you could shed some light on it. Would really appreciate it.

[2020-01-17 00:54:05,808: CRITICAL/ForkPoolWorker-1] mentions.tasks.incoming_webmentions.process_incoming_webmention[4d793826-23dd-4a45-9586-4e53913d9d87]: Failed to process incoming webmention! BAD CONFIG: urlpattern must include a kwarg entry called 'model_name': ResolverMatch(func=writings.views.PostDetailView, args=(), kwargs={'slug': '2020-goals'}, url_name=post, app_names=[], namespaces=[], route=<slug:slug>)

Here I am told that I need to include 'model_name' in the kwargs. I am not entirely sure I what to do here. This is what I currently have in my Post model:

 def get_absolute_url(self) -> str:
        return reverse('post', kwargs={'slug': self.slug})

Should I do something like this?...

 def get_absolute_url(self) -> str:
        return reverse('post', kwargs={'slug': self.slug, 'model_name':'writings.models.Post'})

This does not work unfortunately. Would appreciate any help. Thanks a ton in advance.

rasulkireev commented 4 years ago

I was able to figure out that the model_name kwarg needs to go to app/urls.py, like so:

path('<slug:slug>', PostDetailView.as_view(),kwargs={'model_name': 'writings.Post'}, name='post'),

with the get_absolute_url :

def get_absolute_url(self) -> str:
        return reverse('post', kwargs={'slug': self.slug})

However the new issue is more Django related, I haven't been able to figure it out in a couple of hours of research.

Celery return with the following error:

[2020-01-17 02:20:30,051: ERROR/ForkPoolWorker-1] Task mentions.tasks.incoming_webmentions.process_incoming_webmention[5917507d-2169-45c2-ab93-ea959d6b9421] raised unexpected: ValueError('too many values to unpack (expected 2)',)
Traceback (most recent call last):
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/celery/app/trace.py", line 385, in trace_task
    R = retval = fun(*args, **kwargs)
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/celery/app/trace.py", line 650, in __protected_call__
    return self.run(*args, **kwargs)
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/mentions/tasks/incoming_webmentions.py", line 42, in process_incoming_webmention
    obj = _get_target_object(target)
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/mentions/tasks/incoming_webmentions.py", line 111, in _get_target_object
    return get_model_for_url_path(path)
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/mentions/util.py", line 63, in get_model_for_url_path
    model = apps.get_model(model_name)
  File "/var/www/dj-pw/venv/lib/python3.6/site-packages/django/apps/registry.py", line 203, in get_model
    app_label, model_name = app_label.split('.')
ValueError: too many values to unpack (expected 2)

As far as I understand, this meant that my model_name was not "rendering" correctly. Since the split function uses the '.' as a separator the line above should become app_label -> "writings" and model_name -> "Post". It hasn't worked out that way apparently. Here are other iterations I have tried:

path('<slug:slug>', PostDetailView.as_view(),kwargs={'app_label': 'writings.Post'}, name='post'),
path('<slug:slug>', PostDetailView.as_view(),kwargs={'model_name': 'writings.models.Post'}, name='post'),

That's it. Just for the reference, here is my writings/views.py:

class PostDetailView(DetailView):
    model = Post
    template_name = 'writings/post.html'

    def get_context_data(self, **kwargs):
        current_post = Post.objects.get(slug=self.kwargs['slug'])
        context = super().get_context_data(**kwargs)
        context ['webmentions'] = Webmention.objects.all()

        return context

Hopefully this is not too much detail. I feel like I am getting closer and closer to making this work. Just need a final push. Thanks for the help in advance.

Best, Rasul

beatonma commented 4 years ago

The detail is very much appreciated!

path('<slug:slug>', PostDetailView.as_view(),kwargs={'app_label': 'writings.Post'}, name='post'),

path('<slug:slug>', PostDetailView.as_view(),kwargs={'model_name': 'writings.models.Post'}, name='post'),

I think you're very close - these lines had the right kwarg key with the wrong value and vice versa! Try path('<slug:slug>', PostDetailView.as_view(),kwargs={'model_name': 'writings.Post'}, name='post'),


If that still doesn't work: The too many values to unpack error is raised by django.apps.apps.get_model. Try opening a Django shell with python manage.py shell and do:

import django
django.setup()
from django.apps import apps
apps.get_model('writings.Post')

...and see what you get - you should see something like <class 'writings.models.Post'>. If not then there's something else wrong somewhere - let me know how you get on.

rasulkireev commented 4 years ago

I swear to god I thought I have tried that path initially and it didn't work. But after copy pasting the line you gave me it totally worked!!

path('<slug:slug>', PostDetailView.as_view(),kwargs={'model_name': 'writings.Post'}, name='post'),

I received a webmention from your website. I am very happy. Thanks for the help. As I explore webmentions (and django-wm more specifically) in more detail I will try to contribute more to this package to make more accessible to everyone.

Thanks for your work and your help

beatonma commented 4 years ago

That's great to hear, glad it's working for you!