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

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.

Related

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 best to initialize one-time-only Django objects which can't be fixtures?

I am writing an app in Django which has a few sitewide fixed objects I need to instantiate which, for one reason or another, can't be fixtures.
For example, some (e.g. Permissions) I can't hardcode a PK for because I can't be sure that they'll be loaded in a certain order (and if I use pk=null then I get an IntegrityError if they exist already.)
Others (e.g. Sites) depend on values in settings.py. Edit: These need to run each time the project is deployed, otherwise I could use South's data migrations as per super9's suggestion below.
Since these are Django models, they're not directly related to any of the apps in my project. It would make the most sense to load them in settings.py but that results in a circular import. It works in urls.py but putting the loading code there seems hackish and out-of-place.
I looked into hooking a receiver into post_syncdb as follows:
#receiver(post_syncdb)
def create_groups_and_permissions(sender, **kwargs):
print "Creating groups and permissions"
u_ct = ContentType.objects.get(model="user")
Group.objects.get_or_create(name='Group 1')
Permission.objects.get_or_create(name="Perm 1", codename="perm_1", content_type=u_ct)
However, since I'm using South, per the documentation it only sends post_syncdb when the table is first created. I could call syncdb manually after each time I migrate but would prefer not to.
I am nearly resolved to put them in urls.py or the most closely related app's models.py but thought I'd check here to see if there's an accepted way of loading fixed objects which can't be loaded as fixtures.
Have you checked out data migrations in south yet? http://south.aeracode.org/docs/tutorial/part3.html
Sounds like it might be what you need.

Use custom Comment app and the default Comment from 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.

django: how to add home link to admin

I would like to add a link to / to every page in template. Can I do it without changing django internal template? I could customize django, but this is something I seriously wouldn't like to do.
Sure, just override one of the Django admin templates in your own templates/admin directory. For instance, copy the contents of django/contrib/admin/templates/base.html into yourproject/templates/admin/base.html. Then, change the latter to your heart's content.
See: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#overriding-admin-templates
According to the accepted answer, I still failed to make it. After some try-error experiments, my answer is:
copy django/contrib/admin/templates/base_site.html to as your_project/templates/admin/base_site.html
customize your local base_site.html to whatever you want
add to your settings.py
TEMPLATE_DIRS = ('templates',)

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.