How to create a multiplechoice form with models queryset? - python

The goal of this application is to let users select their favourite fonts using checkboxes and use the selected fonts somewhere else.
The thing is that, all the fonts are entered through the Admin panel by the admin, so the form should be able to get it from there.
This is what I thought doing :
forms.py
class ContactForm1(forms.ModelForm):
choice = forms.MultipleChoiceField(choices=""" Get my models title as choice """, widget=forms.CheckboxSelectMultiple())
class Meta:
model = ImageCheckView
fields = ['title', 'choice']
...
models.py
class ImageCheckView(models.Model):
title = models.CharField(max_length=100, unique=True)
...
What it will have to look like :
(I want to keep the selected options so I can use it somewhere else.)
How can I achieve the following ?

Found a solution, I can create a new checkbox field on my forms and pass the object choices like this :
checkbox = forms.MultipleChoiceField(ImageCheckView.objects.all(), widget=forms.CheckboxSelectMultiple)

Related

Django Admin: change select box for foreign key to search autocomplete, like search objects

The Django admin panel has a search autocomplete with search_fields on the list of objects of a model, but right now I have 3000 users. To add a user manually is dificult with the selectbox; I need the same behavior like the searchfields for selecting a user foreinkey User.
How can I include the Django search feature on the form for editing inside the admin panel?
from myapp.models import Red
from django.contrib.auth.models import User
class Red(models.Model):
customer = models.ForeignKey(User, verbose_name="Cliente")
pub_date = models.DateTimeField(default=datetime.now, blank=True)
Since Django 2.0, you can use autocomplete_fields to generate autocomplete fields for foreign keys.
class UserAdmin(admin.ModelAdmin):
search_fields = ['username', 'email']
class RedAdmin(admin.ModelAdmin):
autocomplete_fields = ['customer']
Django has no built-in autocomplete functionality for foreign keys on admin but the raw_id_fields option may help:
class RedAdmin(admin.ModelAdmin):
raw_id_fields = ("customer", )
If you want real autocomplete then you have to use 3rd-party app like django-autocomplete-light or some of the other solutions.

Making a field un-editable doesn't allow me to pre-populate fields

I'm writing a model called talk that has two fields title and slug. slug is a field which I do not wish the user to be able to edit and is pre-populated based on title. The model looks like this:
class talk(models.Model):
title = models.CharField(max_length = 255)
slug = models.SlugField(editable=False)
In my admin.py I have the following:
class talkAdmin(admin.ModelAdmin):
prepopulated_fields = {"slug": ("title",)}
Trying to access the model in the CMS gives me the error Exception Value: u"Key 'slug' not found in Form". If I remove editable=False everything works as desired except the user can edit the slug as they see fit.
I would like the slug field to appear in the admin but be greyed out so the user can see the slug, but can not change it.
You should use readonly_fields in the ModelAdmin class, not editable in the model.

Radio Button on Many-to-Many field using Inline ModelAdmin

Heres the scenario :
class Account(model.Model):
acc_name = models.CharField(max_length=50)
class Person(model.Model):
accounts = models.ManyToManyField(Account)
class Message(model.Model):
person = models.ForeignKey(Person)
msg = models.CharField(max_length=500)
Now I am using InineModelAdmin in my admin.py. So it looks like this :
class Account(admin.ModelAdmin):
...
some code
...
admin.site.register(Account, AccountAdmin)
class MessageInLine(admin.StackedInline):
model = Message
class PersonAdmin(admin.Modeladmin):
inlines = [MessageInLine]
admin.site.register(Person, PersonAdmin)
So it stands that Message has a ForeignKey on Person and Person has a Many-To-Many with Account.
Now in the Django-admin, where I add Person it obviously gives the components of Person and Message. Now here the accounts are in a list, where they need to be selected by holding CTRL. I want to use a radio_button to allow selecting multiple buttons for faster selection. How can I do this?
Edit :
I tried using radio_field like this inside PersonAdmin :
radio_fields = {"accounts":admin.VERTICAL}
But it gives me an error that says that it is nether a ForeignKey nor does it have a Choices Set So obviously this isnt working. Is there a way around this?
From this Answer seems there is a way using CheckboxSelectMultiple
from django.forms.widgets import CheckboxSelectMultiple
class PersonAdmin(admin.ModelAdmin):
inlines = [MessageInLine]
formfield_overrides = {
models.ManyToManyField: {'widget': CheckboxSelectMultiple},
}
Please read the another question too

Set Django ModelForm visible fields at runtime?

I have a Django model:
class Customer(models.Model):
first_name=models.CharField(max_length=20,null=True, blank=True)
last_name=models.CharField(max_length=25,null=True, blank=True)
address=models.CharField(max_length=60,null=True, blank=True)
address2=models.CharField(max_length=60,null=True, blank=True)
city=models.CharField(max_length=40,null=True, blank=True)
state=models.CharField(max_length=2,null=True, blank=True)
From there, I created a ModelForm:
class CustomerForm(forms.ModelForm):
class Meta:
model=Customer
I'd like to be able to show pieces of the form in my template corresponding to specific information the users can change. For example, if I want to let the customers change their name, I'd like to be able to show a form that only has the fields 'first_name' and 'last_name'.
One way to do this would be to create a ModelForm for each of the various field snippets... for the name example, it would look something like:
class CustomerFormName(forms.ModelForm):
class Meta:
model=Customer
fields=('first_name','last_name')
This seems pretty inelegant, and inflexible. What I'd like to do is be able to specify the fields at runtime, so when I pass the dictionary from the view to the template, I can just set which fields I'd like to show. How can I set it up so that I set the fields for a form at runtime? I'd ideally like the final dictionary passed to look something like this:
{'name_change_form':CustomerFormName(<form with only first_name and last_name>), 'address_change_form':CustomerFormName(<form with only address fields>)}
Then, I know that whenever I output name_change_form.as_p, it'll have exactly the form fields that I'm looking for.
Thoughts? Also feel free to recommend a better way to do it.
from django.forms import ModelForm
from wherever import Customer
def formClassFactory(model,fields):
ff = fields
mm = model
class formClass(ModelForm):
class Meta:
model = mm
fields = ff
return formClass
form_class = formClassFactory( ('first_name','last_name') )

In Django Admin, I want to change how foreign keys are displayed in a Many-Many Relationship admin widget

I have a ManyToMany relationship:
class Book:
title = models.CharField(...)
isbn = models.CharField(...)
def unicode(self):
return self.title
def ISBN(self):
return self.isbn
class Author:
name = models.CharField(...)
books = models.ManyToManyField(Book...)
In the admin interface for Author I get a multiple select list that uses the unicode display for books. I want to change the list in two ways:
1) Only for the admin interface I want to display the ISBN number, everywhere else I just print out a "Book" object I want the title displayed.
2) How could I use a better widget than MultipleSelectList for the ManyToMany. How could I specify to use a CheckBoxSelectList instead?
To display the ISBN you could make a custom field like this:
class BooksField(forms.ModelMultipleChoiceField):
def label_from_instance(self, obj):
return obj.isbn
There's a CheckboxSelectMultiple for the ManyToManyField but it doesn't display correctly on the admin, so you could also write some css to fix that.
You need to create a form for the model, and use that in your admin class:
class AuthorForm(forms.ModelForm):
books = BooksField(Book.objects.all(), widget=forms.CheckboxSelectMultiple)
class Meta:
model = Author
class Media:
css = {
'all': ('booksfield.css',)
}
class AuthorAdmin(admin.ModelAdmin):
form = AuthorForm
For 2), use this in your AuthorAdmin class:
raw_id_fields = ['books']
Check here: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#ref-contrib-admin for instructions on creating a custom ModelAdmin class. I've thought about this a lot myself for my own Django project, and I think 1) would require modifying the admin template for viewing Author objects.

Categories