Put model's id in hidden input in template - python

I would like to put a hidden input in my template containing my model's id. This is what I have:
models.py:
class MyModel(models.Model):
name = models.CharField(max_length=10)
class MyModelForm(ModelForm):
class Meta:
model = MyModel
fields = ['name']
widgets = {
'name': TextInput(),
}
index.html:
{{ form.name.label_tag }}
{{ form.name }}
This works fine and displays a simple form with a text input. What I want to do is add a hidden input that contains the model's id. I tried:
models.py:
class MyModel(models.Model):
name = models.CharField(max_length=10)
class MyModelForm(ModelForm):
class Meta:
model = MyModel
fields = ['name', 'id']
widgets = {
'name': TextInput(),
'id': HiddenInput(),
}
index.html:
{{ form.name.label_tag }}
{{ form.name }}
{{ form.id }}
But it doesn't work. If possible I wanted to avoid manually doing this:
index.html:
{{ form.name.label_tag }}
{{ form.name }}
<input type="hidden" name="id" value="{{ form.instance.id }}">
Thanks!
UPDATE
My overall goal is to have a form that edits an existing model. So I retrieve a model using the ORM and display it on the form. When I submit the form to update the object, I need to know its id in order for the ORM to know which object to update. Thanks!

Related

Django templates using buttons for Boolean fields

I have a preferences page that has many Boolean fields. I created an UpdateView and when I use {{ form.as_p }} in my template it works, but I am trying to create individual buttons for each option instead of checkboxes. I couldn't find a way to make it work in my template.
models.py:
class Preference(models.Model):
user = models.OneToOneField("User", on_delete=models.SET_NULL, null=True)
option1= models.BooleanField(default=False)
option2= models.BooleanField(default=False)
option3= models.BooleanField(default=False)
option4= models.BooleanField(default=False)
views.py:
class preferencesview(UpdateView):
model = Preference
form_class = PreferenceForm
success_url = reverse_lazy("profiles:preferences")
forms.py:
class PreferenceForm (forms.ModelForm):
class Meta:
model = Preference
exclude = ['user']
I want to have individual buttons for each option and a submit button to save the changes. Please let me know if you have any documentation or tutorials.
There is so many ways you can do it. But there is no out of the box solution.
My example is with bootstrap css and a little bit of jquery/js:
In form class definition change fields widgets to HiddenInput like:
class PreferenceForm (forms.ModelForm):
class Meta:
model = Preference
exclude = ['user']
widgets = {'option1': forms.HiddenInput,
'option2': forms.HiddenInput,
}
end so on
then in your template loop over fields of form and based on value render the class of button (btn-success/btn-danger):
<form id="myform">
{% for field in form %}
<button type="button" class="btn {% if field.value %} btn-success{% else %}btn-danger{% endif %}"
name="{{ field.name }}">
{{ field.name }}</button>
{{ field }}
{% endfor %}
</form>
don't forget to add {{ field }} itself,
And now with js watch for click on buttons inside #myform and based on hasClass change class of button and value of input:
<script>
$('#myform button').on('click', function () {
let nameof = $(this).attr('name');
if ($(this).hasClass('btn-success')){
$(this).removeClass('btn-success');
$(this).addClass('btn-danger');
$('#myform input[name='+nameof+']').val('False');
} else {
$(this).removeClass('btn-danger');
$(this).addClass('btn-success');
$('#myform input[name='+nameof+']').val('True');
}
});
</script>
That's all. Don't forget to add save button to form.
Its just one of many examples how can you do it.

Django ModelForm with extra fields

So I have this ModelForm in my django project:
class DateForm(ModelForm):
image = forms.ImageField()
class Meta:
model = Date
exclude = ('user',)
the Photo model:
class Photo(models.Model):
date = models.ForeignKey(Date, on_delete=models.CASCADE)
image = models.ImageField(verbose_name='Photos', upload_to='media/date/photos/')
the form:
<p class="p-form">Title</p>
{{ form.title }}
<p class="p-form">Description</p>
{{ form.description }}
<p class="p-form">Place</p>
{{ form.place }}
<p class="p-form">Rating</p>
{{ form.rating }}
<p class="p-form">Photos</p>
{{ form.image }}
Whenever I try to save my form, its form_invalid method is being called and it doesn't save the form. What is the matter? How do I save extra field of ForeignKey model? How can I get that images sent via form? Thanks!

Style CheckboxSelectMultiple form field. Django

I have a form which has one checkboxselectmultiple field:
class CreateRecipeForm(forms.ModelForm):
class Meta:
model = Recipe
fields = ('name', 'image', 'description', 'cooking_time', 'tags')
widgets = {
...
'tags': forms.CheckboxSelectMultiple(),
...
}
I can iterate through field's options like:
{% for option in form.tags %}
{{ option.tag }} {{ option.choice_label }}
{% endfor %}
How would I render {{ option.tag }} as an input field? i.e:
<input type="checkbox"...>
Thanks.
In fact after reading some django docs on this topic I understood that that the fields of CheckboxSelectMultiple are already rendered as input fields. So if you don't need to add specific values to each field you can do it straight in form by adding attrs to widget:
widgets = {
...
'tags': forms.CheckboxSelectMultiple(attrs={'class': 'anyclass'}),
...
}
But if you need to add different parameters to each field you can do it in template this way:
{% for obj_choice, obj_value in form.obj.field.choices %}
<div class="tags__item">
<input type="checkbox" name="tags" value="{{obj_choice.instance.pk}}"
id="id_{{obj_choice.instance.value}}"
class="tags__checkbox tags__checkbox_style_{{obj_choice.instance.style}}">
<label for="id_{{obj_choice.instance.value}}" class="tags__label">
{{obj_choice.instance.template_name}}
</label>
</div>
{% endfor %}

Django pass variables to form_class

I am trying to figure out how to access fields from a Model that is used as a ForeignKey within the Model that the forms are querying.
Each Room has a form where the user selects a Layout from a dynamic list of possible Layout objects.
1—The HTML forms/room/update/layouts.html
<form class="layouts__form form-horizontal" action="" method="post" enctype="multipart/form-data">
<fieldset class="form__options">
{% csrf_token %}
{% for field in form.layout %}
<div class="layouts__layout">
{{ field.tag }}
{{ field.choice_label }}
<label for="value_{{ forloop.counter0 }}">
<div class="layouts__layout__thumbnail layouts__layout__thumbnail--{{ field.choice_label }}" style="background-image: url('### (I WOULD LIKE TO LOAD 'Layout.thumbnail' HERE) ###');"></div>
</label>
</div>
{% endfor %}
<div class="form__submit">
<button type="submit">Submit</button>
</div>
</fieldset>
</form>
2—The form is being called by this in views.py:
class RoomLayoutView(UpdateView):
model = Room
form_class = RoomLayoutForm
template_name = 'forms/room/update/layouts.html'
3—Which is being created by this in forms.py:
class RoomLayoutForm(forms.ModelForm):
layout = forms.ModelChoiceField(
widget=forms.RadioSelect(attrs={'type': 'radio', 'id': 'value',}),
queryset=Layout.objects.all(),
required=False, empty_label=None)
class Meta:
model = Room
fields = ['layout']
4—Which uses the Room model from:
class Room(models.Model):
title = models.CharField(max_length=200, blank=True)
layout = models.ForeignKey(Layout, related_name='template_selected', blank=True, null=True)
def __str__(self):
return self.title
5—Which takes one of the Layout models as a ForeignKey defined here:
class Layout(models.Model):
title = models.CharField(max_length=200)
...
padding_top = models.IntegerField(blank=False, default=0)
...
thumbnail = models.FileField(upload_to='layouts')
created = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ('-title',)
def __str__(self):
return self.title
I am trying to figure out how to access attributes from Layout model within the actual form. I would especially like to dynamically load the Layout.thumbnail or Layout.padding_top within the form at the top. I have tried at least 8 different methods and was unable to figure out a way to make this work. Any help would be really appreciated.
As stated in this answer, you can access the current instance associated with the form like this in your template:
{{ form.instance }}
So to access the thumbnail or padding_top attributes of the linked layout:
{{ form.instance.layout.thumbnail }}
{{ form.instance.layout.padding_top }}

How to make custom Django CheckboxSelectMultiple without nested input

I'm using Django 1.9.1.
I have a form that has Categories like this:
class MyModelEditForm(forms.ModelForm):
class Meta:
model = MyModel
fields = ['name',
'email',
'categories',
]
widgets = {
'categories': forms.CheckboxSelectMultiple(),
}
Here's the Models:
class MyModel(models.Model):
name = models.CharField(max_length=256, verbose_name='navn')
email = models.EmailField(null=True, blank=True)
categories = models.ManyToManyField(Category)
class Category(models.Model):
name = models.CharField(max_length=128)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
When I use my form in a template I can say {{ form.categories }} and I get a bunch of checkboxes with all my categories! Excellent, functionally this is exactly what I want. And like this, everything works. My problem is that I don't want the input fields nested in labels, as Django defaults to.
So I tried to loop over the categories like this:
{% for category in form.categories %}
<input type="checkbox" name="{{ category.name }}" class="styled-checkbox" value="{{ category.id }}" id="{{ category.id_for_label }}" {% if category.is_checked %}checked="checked"{% endif %}>
<label for="{{ category.id_for_label }}">{{ category.choice_label }}</label>
{% endfor %}
But apparently I can't set the value to {{ category.id }}, it renders nothing. I also tried {{ category.related__id }} but that's not a thing either. Looked in the documentation, but it doesn't really seem to say allot about this issue. If there's a way to only output the input tag and that would be acceptable as well.
So is it even possible to access the related objects id from here? Or is there another way to customise the output? I looked at overriding the render() method, but it seemed like a huge effort just to move the input outside of a label tag.

Categories

Resources