In a form I have a dropdown list , the default behaviour of django seems to fill the first entry with ----------.
How can I remove this, so it will just use the firs entry as the default?
(note that the entries may change, so hardcoding a value for initial= might not work. )
model:
class Job(models.Model):
...
category = models.ForeignKey(Category, on_delete=models.PROTECT)
Try with:
Test 1
class Job(models.Model):
...
category = models.ForeignKey(Category,default="Design" on_delete=models.PROTECT)
As a ForeignKey all related field will have Design as default
Test 2
override the display in Django Admin by create a form.py and register it in the admin.py file and set the default selected value
Related
I am encountering what seems to me a weird bug when rendering Inline forms on the "Add" view of a ModelAdmin.
Here is a minimum example with Django version 2.2.4.
in models.py:
class MyModel(models.Model):
text = models.CharField(max_length=100)
class RelatedModel(models.Model):
parent = models.ForeignKey(MyModel, null=False, on_delete=models.CASCADE)
number = models.DecimalField(decimal_places=2, max_digits=10, null=False, blank=False)
in admin.py:
class RelatedModelInlineTabular(admin.TabularInline):
model = RelatedModel
show_change_link = False
fields = ("number", )
class TestMyModelCreate(admin.ModelAdmin):
fields = ['text', ]
inlines = [RelatedModelInlineTabular]
admin.site.register(MyModel, TestMyModelCreate)
Steps to replicate
Login to django admin website
open the "add" view for MyModel (i.e. navigate to the list of Models and click on the "Add new" button)
Expected result
The form displays an empty text field. Below that, an Inline form is displayed with 3 empty rows for potential related instances of RelatedModel
Actual result
The Inline form is displayed twice, each instance with its own 3 empty rows, as if I had specified it twice.
I attach a screenshot below of the actual page (Discount is the name of the related Model). I tried and I get the same result with both StackedInline and TabularInline.
Am I making some trivial error here that could explain what's happening? Or is this is a known bug? Thank you in advance to anyone that will help.
I have a very basic Django Model and use it in Django REST Framework.
When using the browsable API tool and requesting an instance of a ressource, I can set the values of the different attributes using the HTML form at the bottom of the page. All attributes have their current value pre-set except for the DateTime fields. Is there a special setting required such that the form fields for DateTime entries field are prefilled with their current value?
Model class:
class C(models.Model):
OrderDate = models.DateTimeField(auto_now=False)
p1 = models.ForeignKey(PA, related_name="cs", on_delete=models.CASCADE, null=True)
p2 = models.ForeignKey(PB, related_name="cs", on_delete=models.DO_NOTHING, null=True)
class Meta:
ordering = ['OrderDate']
View:
class CViewSet(viewsets.ModelViewSet):
queryset = C.objects.all().order_by('-OrderDate')
serializer_class = CSerializer
def get_queryset(self):
cs = C.objects.all()
# Some filters...
return cs
Serializer:
class CSerializer(serializers.HyperlinkedModelSerializer):
p1 = PASerializer(many=False, read_only=True)
p2 = PBSerializer(many=False, read_only=True)
class Meta:
model = C
fields = (
'id',
'OrderDate',
'p1',
'p2',
)
I tried to generalize the code hope the general idea is clear.
I would like that the OrderDate field is prefilled with the current value when the HTML form in the browsable API is shown.
in DateTimeField you have 2 options, add a default value or use auto_now_add.
in your situation you have set auto_now, and according to this question
auto_now - updates the value of field to current time and date every time the Model.save() is called.
auto_now_add - updates the value with the time and date of creation of record.
so you have this two possibilities:
OrderDate = models.DateTimeField(default=datetime.now)
or
OrderDate = models.DateTimeField(auto_now_add=True)
This is work if you want to automatically add the current time when a user submit the form without displaying it in your HTML, if you want to display the current date and time in html field (your Form), then you have to set it in the frontend side using JavaScript and HTML
Use: <input type="datetime-local">
I'm new to django drf and had the same problem, and this solved it. (DATETIME_FORMAT in settings.py)
my guess is because when rendering the html it uses a different format than the one DRF uses
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS':
'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
'DATETIME_FORMAT' : '%Y-%m-%dT%H:%M',
}
I hope the title of this question is as it should be based on this explanation below.
I have a model as below:
class Setting(models.Model):
TYPE_CHOICES = (
('CONFIG', 'Config'),
('PREFS', 'Prefs'),
)
attribute = models.CharField(max_length=100, unique=True)
value = models.CharField(max_length=200)
description = models.CharField(max_length=300)
type = models.CharField(max_length=30, choices=TYPE_CHOICES)
is_active = models.BooleanField(_('Active'), default=True)
I use this to save settings. I have don't know all settings in advance and they can change in future. So I decided to save attributes and their values in this model instead of creating columns for each setting(attribute in the model).
Now the problem I am facing is how do I present form with all attributes as fields so that a user can fill in appropriate values.
Right now, as you can see, form shows columns 'Attribute' and "Value" as labels. I would like it to show value of column 'Attribute' as label and column 'Value' as field input.
For example, in Setting model I have this:
Attribute ------------ Value
'Accept Cash' ---------- 'No'
I would like to appear this on form as
<Label>: <Input>
'Accept Cash': 'No'
I think I will have to build form fields from the database(Setting model). I am new to this and have no idea how to begin with it any example or link to tutorial that would help me get started will be much appreciated.
Thank you
you can define a model form based on your Settings model. Check the django documentation on Django Model Forms. The basic definition of the model form should be something like this
Define a forms.py file in your current django app and put the following code in it.
from django import forms
from .models import Settings
class SettingsForm(forms.ModelForm):
class Meta:
model = Settings
fields = ['the fields you want to add'] # or use '__all__' without the parentheses for all fields
Then in your views.py file navigate to the function which renders the page containing the form and add this to it
from .forms import SettingsForm
def your_function(request):
....
context = {
....
'form':SettingsForm()
}
return render(request, 'template_name.html', context)
Now in your template add the form using
........
{{ form }}
.......
I want to create a Django model Field (IntegerField) with a default value, and also create a form derived from the model, where the field is optional. If it's not set on the form, then when I save the form, I want the default value saved to the DB.
# model.py
class Invoice(models.Model):
# IntegrityError "Column 'expireDays' cannot be null"
expireDays = models.PositiveSmallIntegerField(default=1)
# expireDays = *null* in DB
expireDays = models.PositiveSmallIntegerField(default=1, blank=True, null=True)
# forms.py
class InvoiceForm(forms.ModelForm):
# leaving this line out gives invalid form
expireDays = forms.IntegerField(required=False)
class Meta:
model = Invoice
(I used only one of the field declaration lines at a time. :)
I'm not even sure that I'm declaring the default value correctly. The only reference I could find to it was in an article on handling choices by James Bennett. I have yet to find it in the Django docs (I'm using version 1.2 - maybe it's in 1.3?)
Update - I tried setting the field's default value in the MySql database, to no effect. It seems as if, even when the form does not have a value for the field, it goes ahead and assigns null to the DB, over-riding the MySql default value.
Although I am currently just setting a default value in the view that creates the form - I don't really like that, since it puts the responsibility for the field's integrity in the view, not the DB.
The way I would have thought it would work, is that the field could be set, or not, in the form - if set, that value would be written to the DB, and if not set, the DB default would be used. Instead, if not set, the form is writing a null to the DB. So what's the point of having a default value in the ModelField declaration if it's not used? What exactly does it do?
i you want field to be optional - just leave second definition in the model and do not add anything in the form definition:
class Invoice(models.Model):
expireDays = models.PositiveSmallIntegerField(default=1, blank=True, null=True)
class InvoiceForm(forms.ModelForm):
class Meta:
model = Invoice
update, so in case there is no value set, use 1 as the field value:
class InvoiceForm(forms.ModelForm):
def clean_expireDays(self):
exp_days = self.cleaned_data.get('expireDays')
if exp_days is None:
return self.fields['expireDays'].initial
# above can be: return 1
# but now it takes value from model definition
else:
return exp_days
class Meta:
model = Invoice
I have models similar to the following:
class Band(models.Model):
name = models.CharField(unique=True)
class Event(models.Model):
name = models.CharField(max_length=50, unique=True)
bands = models.ManyToManyField(Band)
and essentially I want to use the validation capability offered by a ModelForm that already exists for Event, but I do not want to show the default Multi-Select list (for 'bands') on the page, because the potential length of the related models is extremely long.
I have the following form defined:
class AddEventForm(ModelForm):
class Meta:
model = Event
fields = ('name', )
Which does what is expected for the Model, but of course, validation could care less about the 'bands' field. I've got it working enough to add bands correctly, but there's no correct validation, and it will simply drop bad band IDs.
What should I do so that I can ensure that at least one (correct) band ID has been sent along with my form?
For how I'm sending the band-IDs with auto-complete, see this related question: Django ModelForm Validate custom Autocomplete for M2M, instead of ugly Multi-Select
You can override the default fields in a ModelForm.
class AddEventForm(forms.ModelForm):
band = forms.CharField(max_length=50)
def clean_band(self):
bands = Band.objects.filter(name=band,
self.data.get('band', ''))
if not bands:
raise forms.ValidationError('Please specify a valid band name')
self.cleaned_data['band_id'] = bands[0].id
Then you can use your autocomplete widget, or some other widget. You can also use a custom widget, just pass it into the band field definition: band = forms.CharField(widget=...)