How to create a base serializer to custom generate file field urls - django

I'm using Django's django-private-storage
When an api is created using drf, in the case of a general file field, the url starts with http:// in local and https:// in dev and prod.
But for privateFileField it starts with http:// everywhere.
Therefore, I want to create a BaseSerializer and create a custom url when the field is a privateFileField.
And I want the model serializer with privateFileField to inherit from that serializer.
What should I do?
I could use get_value() function, but I don't want to implement that function in every model serializer with privateFileField. I want to reduce repetition.
Also, the settings that change http:// to https:// are already applied. Only privateFileField is a problem.

Related

django reversing admin urls with underscores

To reverse a model url for Django Admin, you need to write admin:appname_modelname_change . But what if the model name has underscores?
I have a model called AdNetwork inside an app called pubscout, and I am trying to reverse its url.
admin:pubscout_adnetwork_change doesn't work
admin:pubscout_ad_network_change doesn't work either
How to fix this?
Please can you show us your code.
reverse('admin:%s_%s_change' % (app_label, model_name), args=(object_id,))
Something like this should work:
reverse('admin:pubscout_adnetwork_change', args=(object_id,))
... where object_id is an AdNetwork pk.
Please make you have registered the AdNetwork model and hooked the AdminSite instances into your URLconf.
Docs: https://docs.djangoproject.com/en/1.9/ref/contrib/admin/#reversing-admin-urls

how to change django model admin url?

I just need to change
http://localhost:8000/admin/song_management/album/
to
http://localhost:8000/admin/song-management/album/
Note:
I am using ModelAdmin & Changed admin template completely ( ex; Used hardcoded url mostly )
Django's ModelAdmin uses the model's app_label per default to generate the urls. The only way to bypass this would be to subclass AdminSite and change the relevant parts.

Django 'Sites' Model - what is and why is 'SITE_ID = 1'?

I am trying to work with Sites Model of Django.
I dont quite understand why SITE_ID should be SITE_ID = 1.
in the docs:
The ID, as an integer, of the current site in the django_site database
table. This is used so that application data can hook into specific
sites and a single database can manage content for multiple sites.
why 1? what is the current site? this is not clearly explained in the docs.
lets say, I have www.coolsite.com and some other subdomains like www.wow.coolsite.com and www.awesome.coolsite.com
I want to render different content depending on domain name.
my question is, or better, are:
Do I have to add all those domains into Sites Table in DB?
if so, how should I set SITE_ID in settings? Do I have to set all ids like SITE_ID = 1, SITE_ID = 2.. etc?
what does current site has to do with SITE_ID = 1?
I am a bit confused here.
I thought, each Site (e.g. www.wow.coolsite.com) should be a separate django project so that they can have their own settings.py? and in each of those settings.py's, I will set the id of that page from Sites table? but then there are many django projects which also doesnot make sense to me.
Django was created from a set of scripts developed at a newspaper to publish content on multiple domains; using one single content base.
This is where the "sites" module comes in. Its purpose is to mark content to be displayed for different domains.
In previous versions of django, the startproject script automatically added the django.contrib.sites application to INSTALLED_APPS, and when you did syncdb, a default site with the URL example.com was added to your database, and since this was the first site, its ID was 1 and that's where the setting comes from.
Keep in mind that starting from 1.6, this framework is not enabled by default. So if you need it, you must enable it
The SITE_ID setting sets the default site for your project. So, if you don't specify a site, this is the one it will use.
So to configure your application for different domains:
Enable the sites framework
Change the default site from example.com to whatever your default domain is. You can do this from the django shell, or from the admin.
Add your other sites for which you want to publish content to the sites application. Again, you can do this from the django shell just like any other application or from the admin.
Add a foreign key to the Site model in your object site = models.ForeignKey(Site)
Add the site manager on_site = CurrentSiteManager()
Now, when you want to filter content for the default site, or a particular site:
foo = MyObj.on_site.all() # Filters site to whatever is `SITE_ID`
foo = MyObj.objects.all() # Get all objects, irrespective of what site
# they belong to
The documentation has a full set of examples.
Things would be much easier to understand if Django's default SiteAdmin included the id field in the list_display fields.
To do this, you can redefine SiteAdmin (anywhere in your app, but I'd recommend your admin.py or maybe your urls.py) like this:
from django.contrib import admin
from django.contrib.sites.models import Site
admin.site.unregister(Site)
class SiteAdmin(admin.ModelAdmin):
fields = ('id', 'name', 'domain')
readonly_fields = ('id',)
list_display = ('id', 'name', 'domain')
list_display_links = ('name',)
search_fields = ('name', 'domain')
admin.site.register(Site, SiteAdmin)
After including this code snippet, the ID for each "Site" will be shown in the first column of the admin list and inside the form as a read only field. These 'id' fields are what you need to use as SITE_ID:
The concept is that each different site runs in a different application server instance, launched using a different yourdomain_settings.py that then includes a base_settings.py with the rest of the common configuration.
Each of these yourdomain_settings.py will define its own SITE_ID and all other different settings.py parameters that they need to look and be different from each other (static resources, templates, etc.) then you'll define a DJANGO_SETTINGS_MODULE environment variable pointing to that specific yourdomain_settings.py file when launching the application server instance for that domain.
A further note: get_current_site(request) does need request to be available for it to work. If your code doesn't have one, you can use Site.objects.get_current() that however will need a SITE_ID properly defined in the running application server's settings.
This is a late answer but for anyone else having SITE_ID issues and Site problems.
Inside the database, django has a django_site table with(id, domain, name). This is where django stores the SITE_IDs. Mine was actually 5 in the database but i had it set to SITE_ID=1 in the settings.
Knowing that, i can now go back to the database and clear it to get back to zero or use the actual id in the database.
This is covered in the documentation for the Sites framework:
In order to serve different sites in production, you’d create a
separate settings file with each SITE_ID (perhaps importing from a
common settings file to avoid duplicating shared settings) and then
specify the appropriate DJANGO_SETTINGS_MODULE for each site.
But if you didn't want to do it that way, you can not set SITE_ID at all and just look up the current site based on the domain name in your views using get_current_site:
from django.contrib.sites.shortcuts import get_current_site
def my_view(request):
current_site = get_current_site(request)
if current_site.domain == 'foo.com':
# Do something
pass
else:
# Do something else.
pass
This link explains it:
You’ll want to create separate settings files for each domain you’re adding; each one will need its own MEDIA_URL and other settings. You’ll also want to do two things to make sure everything works out properly for administering the different sites:
Create a new Site object in your admin for each domain, and put the id of that Site into its settings file as SITE_ID so Django knows which site in the database corresponds to this settings file.
In the settings file for your original site (the one with id 1), add the other sites’ settings files to the ADMIN_FOR setting, to let Django know that this one instance of the admin application will handle all of the sites.
Also, if you wanna figure out how to modify models and set the views You may take a look at this link:
https://django.cowhite.com/blog/managing-multiple-websites-with-a-common-database-in-django-the-sites-framework/

New URL on django admin independent of the apps

I am using django 1.4 and Python 2.7.
I just have a simple requirement where I have to add a new URL to the django admin app. I know how to add URLs which are for the custom apps but am unable figure out how to add URLs which are of the admin app. Please guide me through this.
Basically the full URL should be something like admin/my_url.
UPDATE
I want a way after which I can as well reverse map the URL using admin.
+1 for Jingo's answer to your original question. With your clarifying comment to the answer in mind:
Such a URL is not "independent of the apps", it is a URL for the app "admin".
Adding a URL to the admin site is similar to ModelAdmin, by overriding get_urls():
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#adding-views-to-admin-sites
EDIT:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.AdminSite
is an admin site, by default "the" admin site is instantiated as "django.contrib.admin.site" (and then e.g. your ModelAdmin's are registered against that). So you can subclass AdminSite for your own MyAdminSite and re-define get_urls() there:
from django.contrib.admin import AdminSite
class MyAdminSite(AdminSite):
def get_urls():
...
...
my_admin_site = MyAdminSite()
...
my_admin_site.register(MyModel, MyModelAdmin)
Make sure you use my_admin_site in urls.py instead now:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#hooking-adminsite-instances-into-your-urlconf
Regarding the actual contents of get_urls(),see
https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.get_urls
(of course calling super() of MyAdminSite). Also note the convenient "admin_view" wrapper mentioned there.
P.S.: In theory, you could also just define get_urls() and then monkeypatch the default admin site so that it uses your get_urls() but I don't know if that would actually work - you'd probably have to monkeypatch right after its "first" import...
Just put your desired url mapping before the admin mapping in your root urls.py. The first match for the request will be taken, because django goes the url mappings from top to down. Just remember that you don't use an url the admin normally needs or provides because this will never match with a custom mapping in front of it. HTH!

Django admin - Keep updating a model and do not create more than one

Im not sure how to put this title.
But what I need is a simple model that I can just update everytime. Lets say I have a Settings model ,and these settings I just want to update or change every now and again. So there is no need to add another object to that model.
Is there suck a field or type of admin-model that I can use?
I could otherwise just keep updating the same object, but I do not want the user to be able to just "Add Setting".
in admin you can specify various permissions. to remove the "add" functionality:
class MyModelAdmin(admin.ModelAdmin):
def has_add_permission(self, request): return False
make sure you create your first and only settings object when you deploy the application.
here is a discussion about singleton models in django: How about having a SingletonModel in Django?