0

I'm trying to create an editable Help page for users on my website using Django v1.11 and Trumbowyg. What I'm trying to accomplish is:

  1. Only allowing a superuser to edit the page via a button visible to them
  2. Using the Trumbowyg editor to enter and edit the text
  3. Saving that text and then displaying it as html on the page

Naturally, I thought that I should create a model for the HelpText which would hold the text put into the Trumbowyg editor. However, this model would have to be special in that there can only be one of them. So I turned to the Singleton Model. I followed this tutorial and created a SingletonModel model and subclassed it for my HelpText model like so.

class SingletonModel(models.Model):

    class Meta:
        abstract = True

    def save(self, *args, **kwargs):
        self.pk = 1
        super(HelpText, self).save(*args, **kwargs)


    def delete(self, *args, **kwargs):
        pass

    @classmethod
    def load(cls):
         obj, created = cls.objects.get_or_create(pk=1)
         return obj

class HelpText(SingletonModel):
    text = models.TextField(blank=True)

However, after registering HelpText to my admin.py this gave me an error.

the model s is abstract so it cannot be registered with admin.' model.__name__

From a couple of google searches, I found that the problem was that in class Meta, abstract is set to true. I could not figure out how to get rid of this error so instead I thought, "Hey! If the problem is that abstract is set to true then lets nuke the SingletonModel class completely and just put its methods into HelpText." So then I did this.

class HelpText(models.Model):

    text = models.TextField(blank=True)

    def save(self, *args, **kwargs):
        self.pk = 1
        super(HelpText, self).save(*args, **kwargs)


    def delete(self, *args, **kwargs):
        pass

    @classmethod
    def load(cls):
        obj, created = cls.objects.get_or_create(pk=1)
        return obj

    def __str__(self):
        return self.help_text

Surprisingly, I got an error for this too but of a crueler variety. Now, Django is telling me when I load my help page that "name 'self' is not defined." I have no idea how this is possible considering that I have several other models that use def__str__(self) to define their string methods and blatantly use self to refer to its own fields. How is this happening? The error also occurs in the help_landing method in views.py on the line help_text = webapp_models.HelpText.load(). The views and templates relevant to this model are below.

views.py

@login_required(login_url=LEADER_LOGIN_URL)
def help_landing(request):
    # Variable to decide if the edit button exists on the help_landing page
    super_can_edit = is_superuser(request.user)
    help_text = webapp_models.HelpText.load()

    context = {
        'include_back': True,
        'include_home': True,
        'description': 'Help',
        'super_can_edit': super_can_edit,
        'help_text': help_text,
    }

    return render(request, 'leader/help_landing.html', context)

@login_required(login_url=LEADER_LOGIN_URL)
def help_create_landing(request):
    help_text = webapp_models.HelpText.load()

    context = {
        'include_back': True,
        'include_home': True,
        'description': 'Help Edit',
        'help_text': help_text,
    }

    return render(request, 'leader/help_create_landing', context)

@login_required(login_url=LEADER_LOGIN_URL)
def help_create(request):

    help_text = webapp_models.HelpText.load()

    help_text.update(
        text=request.POST['text'],
        )

    help_text.save()

    return redirect('leader/help_landing')

help_landing.html

{% extends "leader/base.html" %}

{% block extra_css %}
<style>

button {
    background-color: Transparent;
    background-repeat: no-repeat;
    border: none;
    cursor: pointer;
    overflow: hidden;
    outline: none;
}

</style>
{% endblock %}

{% block description %}{{ description }}{% endblock %}

{% block content %}

<div class="ui grid"> 
    <div class="eight wide column"> 
        {% if help_text %}{{ help_text.text }}{% endif %}
    </div>
    {% if super_can_edit %} 
    <div class="six wide column"> 
        <a href="leader/help_create_landing/"> 
            <button class="customButton" type="submit">
              <h2 class="ui header">
                  <i class="big circle add icon"></i>
                    Edit Help Page
              </h2>
            </button>
        </a>
    </div>
    {% endif %}

</div>

{% block javascript %}
<script>

</script>
{% endblock %}

help_create_landing.html

{% extends "leader/base.html" %}

{% block extra_css %}
<style>

button {
    background-color: Transparent;
    background-repeat: no-repeat;
    border: none;
    cursor: pointer;
    overflow: hidden;
    outline: none;
}

</style>
{% endblock %}

{% block description %}{{ description }}{% endblock %}

{% block content %}

<div class="column">
    <form name="helpForm" action="/leader/help_create/" method="post" role="form" enctype="multipart/form-data">{% csrf_token %}
        <div class="ui grid"> 
            <div class="six wide column"> 
                <textarea id="helpEditor" name="text" rows=6 type="text">
                    {% if help_text %}{{ help_text.text }}{% endif %}
                </textarea>
            </div>
            <div class="six wide column"> 
                <button type="submit" id="save">Edit</button>
            </div>
        </div>
    </form>
</div>

{% block javascript %}
<script>
    $(helpEditor).trumbowyg();
</script>


{% endblock %}

Traceback: I'm switching out the website name for security reasons

Environment:


Request Method: GET
Request URL: https://fdev.com/leader/help_landing/

Django Version: 1.11.4
Python Version: 3.5.2
Installed Applications:
['webapp.apps.WebappConfig',
 'leader.apps.LeaderConfig',
 'rest_framework',
 'django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'channels']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback:

File "/home/felix/felix_env/lib/python3.5/site-packages/django/core/handlers/exception.py" in inner
  41.             response = get_response(request)

File "/home/felix/felix_env/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  187.                 response = self.process_exception_by_middleware(e, request)

File "/home/felix/felix_env/lib/python3.5/site-packages/channels/handler.py" in process_exception_by_middleware
  243.             return super(AsgiHandler, self).process_exception_by_middleware(exception, request)

File "/home/felix/felix_env/lib/python3.5/site-packages/django/core/handlers/base.py" in _get_response
  185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/felix/felix_env/lib/python3.5/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
  23.                 return view_func(request, *args, **kwargs)

File "/home/felix/felixserver/leader/views.py" in help_landing
  1892.     help_text = webapp_models.HelpText.load()

File "/home/felix/felixserver/webapp/models.py" in load


Exception Type: NameError at /leader/help_landing/
Exception Value: name 'self' is not defined

When in the Django shell, I can instantiate a HelpText object but if I create more than one I get an error. I believe this is because I made sure that there should always be one HelpText model existing. Here's the traceback.

Traceback (most recent call last):
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: webapp_helptext.id

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/models/query.py", line 394, in create
    obj.save(force_insert=True, using=self.db)
  File "/home/felix/felixserver/webapp/models.py", line 371, in save
    super(HelpText, self).save(*args, **kwargs)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/models/base.py", line 807, in save
    force_update=force_update, update_fields=update_fields)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/models/base.py", line 837, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/models/base.py", line 923, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/models/base.py", line 962, in _do_insert
    using=using, raw=raw)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/models/query.py", line 1076, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/models/sql/compiler.py", line 1107, in execute_sql
    cursor.execute(sql, params)
File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/backends/utils.py", line 80, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/home/felix/felix_env/lib/python3.5/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: webapp_helptext.id
P_Locked
  • 13
  • 6
  • What line is the error occuring on? But I see one thing, which is that in your `__str__` method you refer to `self.help_text`, but the field name is just `text` not `help_text` – little_birdie Jun 12 '19 at 01:27
  • The error occurs in views.py in the method help_landing on this line: `help_text = webapp_models.HelpText.load()` and oops, I forgot to change that to `text`. I just fixed it. – P_Locked Jun 12 '19 at 03:18
  • 1
    The code you have posted would not give that error. Show the real code and the full traceback. – Daniel Roseman Jun 12 '19 at 07:00
  • @EmilioConte Someone has already pointed out the self.help_text. My comment above yours shows that. What do you mean that I can't instantiate it? I'm pretty sure I never instantiate it in the code above. I only used it to create the subclass HelpText model and then in admin.py, I wrote `admin.site.register(HelpText)`. – P_Locked Jun 12 '19 at 17:50
  • @DanielRoseman I assure you that I'm not showing you "fake code" or trying to fool you lmao. This is the real code and I do need help with this error. However, I will post the full traceback in an edit above. – P_Locked Jun 12 '19 at 17:52
  • Indeed my previous comment is not helping, I delete it. Your model works correctly. I imagine that you can instantiate it in console without any error? – Emilio Conte Jun 12 '19 at 19:28
  • Yes I can. When I add more than one, I get an error but I believe that means that my model is working effectively as a singleton model. I really don't understand why Django is telling me that it doesn't understand self. – P_Locked Jun 14 '19 at 00:02

0 Answers0