Django autocomplete Light in list filters for admin - django-forms

I have successfully setup the Autocomplete Registry and have my django admin forms where if you go to the form, the auto completes works. I would like to be able to extend the autocompletes to work on the list_filter view as well. So when you are looking at the view generated by Admin.py -- that the list_filter inputs that are generated would also use the autocomplete jquery + service URL.
I didn't see anything listed in the documentation, anyone have any pointers?

If you are using Django version greater then 2.0, you can try using the built-in autocomplete fields for this purpose.
By default, the admin uses a select-box interface () for those fields. Sometimes you don’t want to incur the overhead of selecting all the related instances to display in the dropdown.
The Select2 input looks similar to the default input but comes with a search feature that loads the options asynchronously
There is a simple app which does this:
To install use: pip install django-admin-autocomplete-filter
Then add admin_auto_filters to your INSTALLED_APPS inside settings.py of your project.
Let's say we have following models:
class Artist(models.Model):
name = models.CharField(max_length=128)
class Album(models.Model):
name = models.CharField(max_length=64)
artist = models.ForeignKey(Artist, on_delete=models.CASCADE)
cover = models.CharField(max_length=256, null=True, default=None)
And you would like to filter results in Album Admin on the basis of artist, then you can define search fields in Artist and then define filter as:
from admin_auto_filters.filters import AutocompleteFilter
class ArtistFilter(AutocompleteFilter):
title = 'Artist' # display title
field_name = 'artist' # name of the foreign key field
class ArtistAdmin(admin.ModelAdmin):
search_fields = ['name'] # this is required for django's autocomplete functionality
...
class AlbumAdmin(admin.ModelAdmin):
list_filter = [ArtistFilter]
'''
defining this class is required for AutocompleteFilter
it's a bug and I am working on it.
'''
class Media:
pass
After following these steps you may see the filter as:

You should define your own admin filter that inherits from django.contrib.admin.SimpleListFilter. Then should provide your own HTML template for this filter which will use one of django-autocomplete-light widgets. As a parameter for widget you should define required autocomplete URL. And do not forget to include proper JS and CSS for it.
All of this is done in special app for this: dal-admin-filters

Related

Django Oscar : User as a partner having limited dashboard access

I'm implementing django-oscar ecommerce and goal is to transform it into a marketplace. Oscar creates abstract_models for each of their apps so any changes required as per use case, a models.py subclasses the same and we can write our custom code there.
As per documentation of Django-Oscar listed here https://django-oscar.readthedocs.io/en/latest/ref/apps/dashboard.html#abstract-models,users need to be given permissions for limited dashboard access allowing them to be recognized as a fulfillment partner and giving them limited dashboard access to create,update,delete products etc.
However, when i checked the abstract_models.py inside partner app, I saw the following 2 implementations which are there by default inside class Partner:
#: A partner can have users assigned to it. This is used
#: for access modelling in the permission-based dashboard
class AbstractPartner(models.Model):
users = models.ManyToManyField(
AUTH_USER_MODEL, related_name="partners",
blank=True, verbose_name=_("Users"))
class Meta:
abstract = True
app_label = 'partner'
ordering = ('name', 'code')
permissions = (('dashboard_access', 'Can access dashboard'), )
verbose_name = _('Fulfillment partner')
verbose_name_plural = _('Fulfillment partners')
However I see that users above are already linked to AUTH_USER_MODEL and the class META has permissions already implemented. Do i need to subs class abstract_models.py and explicitly define permissions like below:
class Partner(AbstractPartner):
users = models.ManyToManyField(
AUTH_USER_MODEL, related_name="partners",
blank=True, verbose_name=_("Users"),
permissions = ['partner.dashboard_access'])
Need help here. Thanks in advance. Also, I'm a beginner in Django, so any statements/assumptions above need to be thoroughly scrutinized.

Django Rest Framework: Disable format extensions

I would like to do something like this:
from rest_framework import routers
router = routers.DefaultRouter(suffix_required=False)
When I look at the definition of DefaultRouter:
class DefaultRouter(SimpleRouter):
"""
The default router extends the SimpleRouter, but also adds in a default
API root view, and adds format suffix patterns to the URLs.
"""
include_root_view = True
include_format_suffixes = True
Notice include_format_suffixes is hardcoded to True.
I must be missing something, but how to I turn off format extensions preferabley for the whole project, or at least for a certain router? I always use JSON, and do not wish to have these .json extensions in the urls created from ViewSets.
I realize I could use Simple router, but I would the " default API root view, that returns a response containing hyperlinks to all the list views" that the DefaultRouter provides.

Bring real data tables with FK

I have 3 classes: Document, Layout and Company
1 Document has 1 Layout and 1 Company.
Document class:
layout = models.ForeignKey (Layout)
company = models.ForeignKey (Company)
I have a search page that is being filled by JSON, then the data layout and the company is returning the ID of them respectively, and the ideal would be to show the names of each data (Name and Company Name Layout).
How can I accomplish this query as quoted above?
You need to define a __unicode__(self): method for Layout and Company.
It might look something like:
class Layout(models.Model):
name = models.CharField(...)
def __unicode__(self):
return self.name
Of course, I'm only guessing at what your Layout class looks like. You'll have to change __unicode__ to make it appropriate for your model.
In the future, try to search the Django Documentation. It's actually quite good. Here's the relevant information for what you're asking. https://docs.djangoproject.com/en/dev/ref/models/instances/#unicode

Editing a Django model with a filefield without re-uploading the file

Below is a simplified version of the django code in my project; it allows users to upload a file and give it a title. This feature works perfectly. However, when user goes re-edit the form later, the file and title are redisplayed, but when the user goes to submit the file filed empties. The file field of the form reopened for editing looks like this:
Currently: media_location/uploadedfile.mp3
Change: [Choose File] No file Chosen
And after I submit it, it's:
This Filed is required
[Choose File] No file Chosen
How do I get it so that the user does not have to reupload the file? It does not matter to me whether the field is made readonly once submission is done, or whether it remains editable. The finished project is not for a client and will only be available to a small group of trusted users, but I would still like to follow best practices if possible. Thanks for any help.
Django Code:
models.py
class Recording(models.Model):
rec_title=models.CharField(max_length=200,blank=True)
rec_file = models.FileField(upload_to='recordings')
forms.py
from django import forms
from songstorage.models import Recording
class RecordingForm(forms.ModelForm):
rec_file=forms.FileField(label='Upload File')
rec_title=forms.CharField(label='Recording Title',required=False)
class Meta:
model=Recording
views.py
def addrecordings(request,recordingfile):
#if there is a recordingfile in the url, the user is editing...
if recordingfile:
recording=Recording.objects.get(rec_title=recordingfile)
recording_form = RecordingForm(instance=recording)
#...Otherwise a new form is createing a new one
else:
recording_form = RecordingForm(request.POST, request.FILES)
#When the form is submitted, do the following:
if request.method == 'POST':
#check if its valid
if recording_form.is_valid():
recording_form.save()
#if sucessfully submitted, redirect
return redirect('/recordings/')
return render_to_response('addrecordings.html',{'recording_form':recording_form},context_instance=RequestContext(request))
I had the same problem.
You can override a model's default clean function. This validates all forms, the user can change the image file on edit, and the file is guaranteed to be nonempty.
class MyModel(models.Model):
image = models.ImageField(blank=True)
def clean(self, *args, **kwargs):
super(MyModel, self).clean(*args, **kwargs)
if not self.image:
raise ValidationError('Please provide an image')
I have had the same problem and couldn't figure out how nor able to search anything useful, my current solution is to use another form, in your scenario:
class RecordingUpdateForm(RecordingForm):
rec_file=forms.FileField(label='Upload File', required=False)
The only difference is I am using UpdateView class based view, so you have to modify your view function to use the RecordingUpdateForm for updating.

django rest frame work tutorial 4 serializer concept

I finished tutorial 1-4 at http://django-rest-framework.org/tutorial/4-authentication-and-permissions.html and got the code run.
However, I am not fully understand the explanation around:
owner = serializers.Field(source='owner.username')
I am confused by which field refering to which field.
1.For example, there is an owner field defined in Snippet class in models.py. After looking it up at https://docs.djangoproject.com/en/dev/ref/models/fields/#foreignkey, it says ForeignKey() returns a class. Does it return the auth.User class?
2.If it does, what "owner" does the
owner = serializers.Field(source='owner.username')
refer to? I do not found owner in the import part of serializers.py.
3.What does serializers.Field(source='owner.username') returns? Does it return the username in the auth.User?
4.Should we add the corresponding field in a serializer class if the corresponding model has a field reference to another table?
source = 'owner.username' will translate to 'user.username' since owner is nothing but FK-User.
Please note that 'owner' on the left side of field is not important here, in your case. i.e, you can still add custom fields like,
xyz = serializers.Field(source='owner.username')

Resources