Use custom Comment app and the default Comment from Django - django

I have a custom comment app but also want to use the original Comment app, without the added fields of my custom app. Is there a way to do this?
Thanks!

Sure, but if you named your custom app "comments" as well, you'll have to be extra careful to keep things straight. It would probably be best to import Django's comment system like so:
from django.contrib import comments as django_comments
You can then access the comment model like:
django_comments.Comment
Which will signal where it's actually coming from at a glance.

Related

Why are my models not showing up in django admin site?

I have made alot of models and forgot to register them when I made them, after I realized I didn't register them I went and registered them the usual way (shown below). I've deleted the database and all migrations (including __pycache__) but haven't deleted the __pycache__ in the inner project folder (that holds settings.py) because I don't know if that would cause problems or not. I've tried using admin.register(Comment,admin) but that didn't work and, as you know, isn't necessary. I'm not sure what other information I would need to give so please let me know what else you need to know. Just so you know, I have 'django.contrib.admin' and 'django.contrib.sites' in the INSTALLED_APPS and also have path('admin/', admin.site.urls) in the project level urls.py
admin.register(PicturePost)
admin.register(VideoPost)
admin.register(TextPost)
admin.register(Comment)
admin.register(Report)
Please use below code because you are not using correct method to register the model. admin.register is method decorator for ModelAdmin class.
admin.site.register(PicturePost)
admin.site.register(VideoPost)
admin.site.register(TextPost)
admin.site.register(Comment)
admin.site.register(Report)
admin.register is a decorator that you should apply to custom ModelAdmin classes - not a function that you can use to register models.
You need to use admin.site.register instead:
admin.site.register(PicturePost)
etc.

Django Admin: How to change model name?

I would like to change the model name displayed in admin. The idea is to be able to register filtered versions of the model to the admin view. I know that I can add filter options when viewing the model. I am not interested in doing that.
I don't think using the approach for solving admin plural naming is an option: Django fix Admin plural. I could be wrong. If so, please tell me how this can be done.
I found this approach which seems to be the right solutions: Change 'Change model class name' in Django Admin || Change the 'Change' <h1>. However, I can't make it work. Is it just me not trying hard enough?
It is also an option to make a number of models and then register each of them. However, I will prefer to rename and register filtered versions in admin.
Any suggestions for solving this little issue?

Showing link in menu conditional on logged in status

Using Mezzanine it's easy to toggle showing or not showing of regular pages using the 'Login necessary' toggle.
I want use this toggle for a Link-type page, unfortunately it's not there. What's the best way to achieve the toggling effect in Mezzanine?
I probably can inherit from the Link class and do something like this
class LoginLink(Link):
login_required = models.BooleanField(_("Login required"), default=False,
help_text=_("If checked, only logged in users can view this page"))
and use LoginLink as the page type instead but I hope there is a better solution. A better solution would have the following:
No new page type
No messing with core Mezzanine
I'm pretty sure my proposed solution works (but I really don't like it). Is it possible to extend the Mezzanine Link type in such a way only my own Link type is visible in the admin?
I've found a solution that's pretty short and sweet. The nice thing is that the login_required is already available for all pages through pages_page so we don't have to do any database modifications. With this solution you lose the option to create the default link type but in my case that's a plus from a usability perspective. One Link type is sufficient. The code for my solutions is as follows and goes into admin.py
# Get the Mezzannine admin logic and the Link model
from mezzanine.pages.admin import LinkAdmin
from mezzanine.pages.models import Link
# Create a custom LoginLink, with the login_required code from the page.
from copy import deepcopy
class LoginLinkAdmin(LinkAdmin):
fieldsets = deepcopy(LinkAdmin.fieldsets) + \
((None, {"fields": ("login_required",)}),)
# Unregister and register the LinkAdmin
admin.site.unregister(Link)
admin.site.register(Link, LoginLinkAdmin)
Adding this should be copy and paste.
Edit
I later found that this is the preferred way in the documentation. However, this only seems to work in my dev environment and not in our production-like environment. Further searching led me to the Model Customization docs. I didn't get this to work but it gave me a new idea. Mezzanine overrides the standard admin.site functionality, as described in this comment in /mezzanine/boot/lazy_admin.py:
"""
Defers calls to register/unregister until autodiscover is called
to avoid load issues with injectable model fields defined by
``settings.EXTRA_MODEL_FIELDS``.
"""
So I've come up with yet another solution. I've put the code above in my urls.py after admin.autodiscover() and deleted it from admin.py. This is ugly but it seems to work.

How to override models defined in installed apps in Django?

Is it possible to redefine a model used in an INSTALLED_APP without modifying the app in question? For example, django-basic-blog has a Post model which I would like to add a field to. I could edit django-basic-blog directly but for code portability I'd like to build on top of it. I don't want to subclass as I want to preserve all existing references to the Post model. Thanks in advance!
If you subclass the original fields will be still stored in the original table, so references would stay valid.
If you want to monkey-patch an existing class, which is mostly not the recommendable dirty method, you could use contribute_to_class in some models.py file that will be loaded in an app after the one you want to modify:
models.py:
from django.db.models import CharField
from blog.models import Post
CharField(max_length="100").contribute_to_class(Post, 'new_field')
If you do it like this, you always have to bare the risk that your changes can clash with other pieces of code and that your code will be harder to maintain!

Doing it right in Django - subclassing instead of hacking

I am using the threadedcomments module and need two changes:
- an additional field on the ThreadedComment model
- different fields on the form
I know the answer is to subclass but I'm not sure how to go about doing this - where does the code go?
As its not clear from you question. I am assuming you are talking about extending django.contrib.comments .
Yes you have to subclass it. Create your own application, and all code (extended models, forms, views etc.) goes there.
Important things, you wont add django.contrib.comments in INSTALLED_APPS list, but add your comment application name(which you inherit from django.contrib.comments).
Also you would need to add
COMMENTS_APP = 'my_comment_app'
to your settings.py
Here is very good example for doing exactly what you want to do.