I have a CreateView to create artists but when submitting the form, nothing happens.
models.py
class Artist(models.Model):
name = models.CharField(max_length=222, unique=True)
slug = models.SlugField(unique=True, null=True)
age = models.PositiveIntegerField(null=True,blank=True)
location = models.CharField(max_length=222, null=True, blank=True)
bio = models.TextField(null=True,blank=True)
booking_fee_per_hour = models.PositiveIntegerField(verbose_name="Booking Fee per hour")
def __str__(self):
return self.name
views.py
class ArtistsAddView(views.CreateView):
template_name = 'add_artist.html'
model = Artist
fields = '__all__'
success_url = '/'
templates -> add-artist.html
<form method="post" action="{% url 'artist add' %}">
<p>{{ form.name.label_tag }} {{ form.name }}</p>
<p>{{ form.age.label_tag }} {{ form.age }}</p>
<p>{{ form.location.label_tag }} {{ form.location }}</p>
<p>{{ form.bio.label_tag }} {{ form.bio }}</p>
<input type="hidden" name="next" value="{{ next }}">
<button>Submit</button>
{% csrf_token %}
</form>
I intentionally hid 2 of the fields: slug and booking_fee_per_hour. I would like to make them available only for admins.
If I write:
<form method="post" action="{% url 'artist add' %}">
{{ form.as_p }}
<input type="hidden" name="next" value="{{ next }}">
<button>Submit</button>
{% csrf_token %}
</form>
then the artist is saved to the DB but also the normal user can see slug and booking_fee_per_hour.
Could you please help me?
I think that as the add-artist.html
template does not include some fields that are mandatory like slug & booking_fee_per_hour
(no blank=True, null = True
), the generic CreateView
cannot saves the model.
Here are several workarounds depending on your app concerns and what is easy to do for you:
Make fields optional in the model (blank=True, null = True
) & populate them later with the correct values
Provide default values for those fields in the model (default=...
)
provide default values in the template with hidden fields <input type="hidden" name="booking_fee_per_hour" value="????">
provide default values in the view. For example you can override the post
method of the class and providing values on the fly when saving. https://docs.djangoproject.com/en/4.1/ref/class-based-views/mixins-editing/#django.views.generic.edit.ProcessFormView
class ArtistsAddView(views.CreateView):
template_name = 'add_artist.html'
model = Artist
fields = '__all__'
success_url = '/'
def post(request, *args, **kwargs)
post_data = request.POST.copy() # make post data mutable
# Add the needed data
post_data['booking_fee_per_hour'] = ...
...
# save
request.POST = post_data
super().post(request, *args, **kwargs)