Django: multiple different fields -> one model - django

I want to show different fields (a html-option-field who gets Mymodel.object.all and a textfield) and save it to one model field.
How can I build this?
MultiValueField (https://docs.djangoproject.com/en/2.1/ref/forms/fields/) doesn't help with different fields?
Has someone an example? How can I define which kind of field it is?
EDIT:
How can I determine which field I want to save in the model-field? I use a ModelForm.

You should use forms.ModelChoiceField(choices=ModelClass.objects.all()) for the choicefield, you can also set the widget to be widget=forms.CheckboxSelectMultiple.
your form can be like
class SuperForm(forms.Form):
cool_field = forms.ModelChoiceField(
choices=ModelClass.objects.all(),
widget=forms.CheckboxSelectMultiple,
)
text_area = forms.CharField(widget=forms.Textarea)

Related

What Django model field do I use for a checkbox form?

I created an HTML form and am now hooking it up to Django. (I know I should have used Django to create the form, but in this case I didn't). In my models.py, I use CharField for textboxes, CharField with choices for select forms, but for checkboxes, what model field do I use? Do I have to create another class for all of the checkbox choices and then link that with a manytomany relationship? Thank you.
Probably a BooleanField:
A true/false field.
The default form widget for this field is a CheckboxInput.
If you need to accept null values then use NullBooleanField instead.
The default value of BooleanField is None when Field.default isn’t defined.
The model field reference page is a good place to find these types of answers.
I've found it helpful to think about my model rather than about HTML forms; if you choose fields based on what your model should have your forms usually work themselves out.
Possible to realize as BooleanField with default options True or False. False gives unchecked box, e.g.:
selected = models.BooleanField(default=False)
well, I don't know if you can do that in the models, but you can use it in forms read this for more information
FAVORITE_COLORS_CHOICES = (
('blue', 'Blue'),
('green', 'Green'),
('black', 'Black'),
)
class SimpleForm(forms.Form):
favorite_colors = forms.MultipleChoiceField(
required=False,
widget=forms.CheckboxSelectMultiple,
choices=FAVORITE_COLORS_CHOICES,
)

access model fields and attributes in django

I'm writing a simple scaffolding app in django, however I'm still not able to access a models fields and attributes(e.g. CharField, max_length=100, null=True, etc...). I know about the _meta class of models, but as far as I know it only retrieves basic info about the model not the fields. Is there a away to achieve this?
Update:
you can find the answer in this article:
http://www.b-list.org/weblog/2007/nov/04/working-models/
You should use the get_field method to get info for a particular field:
field = ModelName._meta.get_field('field_name')
Then you may check various attributes of field, like field.blank, field.null, field.name etc.
If on the other hand you want to get a list of all fields of a Model you should use fields:
fields = ModelName._meta.fields
For example to get the name of all your model fields you can do something like:
field_names = ', '.join(f.name for f in fields)
Hm... also I just noticed that your question is a duplicate of Get model's fields in Django !

Filtering a ManyToMany field to User insida a form in Django

I've got a custom Model called Group with two ManyToMany fields called admins and members (both to the default User model). I've built a form to edit the administrators:
class AddAdminsForm(forms.ModelForm):
class Meta:
model = Group
fields = (
'admins',
)
Now I want to filter the selection options inside the admins field based on whether it is present in the members field. What would be the best way to achieve that? By entirely changing my members/admins architecture or by somehow messing with the __init__ method inside the form class?
I'm not able to check this solution right now but maybe you can:
....
in your function
form.fields['admins'].queryset = Members.objects.all()

Django form validation with values_list in ModelChoiceField

I have a form like this:
class SearchForm(forms.Form):
genus = forms.RegexField(
regex=r'^[a-zA-Z]+$',
required=False,
)
species = forms.RegexField(
regex=r'^[a-zA-Z]+$',
required=False,
)
island_group = forms.ModelChoiceField(
required=False,
queryset=Locality.objects.values_list('islandgroup', flat=True).distinct('islandgroup'),
Now, my form fails validation on the the island_group field as I am not returning model objects. I need to return the values_list to get the distinct entries. There is a bit more to this form which is why I don't want to use a model form.
My question is: what is the best way to get my form to validate?
Any help much appreciated.
Why not override the save method: call some validation function before actual save?
I had the same problem, my solution now is to use the ChoiceField instead of the ModelChoiceField. I believe this makes sense, since we do not want the user to select model instances, but distinct attribute values throughout one table column and the same attribute might well correspond to several model instances.
class SearchForm(forms.Form):
# get the distinct attributes from one column
entries = Locality.objects.values_list('islandgroup', flat=True).distinct('islandgroup')
# change the entries to a valid format for choice field
locality_choices = [(e, e) for e in entries]
# the actual choice field
island_group = forms.ChoiceField(
required=False,
choices=locality_choices)
This way Django's inbuilt validation performs exactly what we want, i.e. checking whether a member of the set of all possible attributes from one column was selected.

Hidden field in Django Model

A while back I made a Model class. I made several ModelForms for it and it worked beautifully.
I recently had to add another optional (blank=True, null=True) field to it so we can store some relationship data between Users. It's essentially a referral system.
The problem is adding this new field has meant the referral field shows up where I haven't changed the ModelForms to exclude it. Normally this would just mean an extra 10 minutes going through and excluding them but in this case, due to project management politics out of my control, I only have control over the Models for this application.
Can I either:
Set the field to auto-exclude?
Set it so it renders as a hidden (acceptable if not perfect)?
If you have access to the template you could render it as a hidden field with the following code:
{{ form.field_name.as_hidden }}
instead of the standard:
{{ form.field_name }}
from the docs on Using a subset of fields on the form:
Set editable=False on the model field. As a result, any form created from the model via ModelForm will not include that field.
You could define a custom model field subclass and override the formfield() method to return a field with a HiddenInput widget. See the documentation for custom fields.
Though you mentioned that you cannot use exclusion in your case, I think others who come across this answer (like myself, based on the title) may find it helpful.
It is possible to selectively hide fields using exclude in ModelAdmin, here is a snippet from something I'm working on:
class ItemsAdmin(admin.ModelAdmin):
form = ItemsForm
actions = None
list_display = ('item_id', 'item_type', 'item_title', 'item_size', 'item_color',)
search_fields = ('item_id', 'item_title',)
inlines = [ImageInline,]
readonly_fields = ('disable_add_date','disable_remove_date',)
exclude = ('add_date', 'remove_date',)
###.............