I'm a Django newbie, and I have a question about reusing the inline formset of the admin interface in the production code. Consider the following model:
class Attribute(models.Model):
name = models.CharField(max_length=50)
class Person(models.Model):
lastName = models.CharField(max_length=50)
firstName = models.CharField(max_length=50)
email = models.CharField(max_length=50)
attributes = models.ManyToManyField(Attribute, through='AttributeValue')
class AttributeValue(models.Model):
person = models.ForeignKey(Person, on_delete=models.CASCADE)
attribute = models.ForeignKey(Attribute, on_delete=models.PROTECT)
isConsumer = models.BooleanField()
value = models.CharField(max_length=50)
The admin interface for this comes out beautifully. I used the following admin.py:
class AttributeValueInline(admin.TabularInline):
model = AttributeValue
extra = 3
class PersonAdmin(admin.ModelAdmin):
list_display = ('lastName', 'firstName','email')
fieldsets = [
('Name', {'fields': ['firstName', 'lastName']}),
('Contact Info',{'fields': ['email','phoneNumber']})
]
inlines = [AttributeValueInline]
admin.site.register(Person, PersonAdmin)
admin.site.register(Attribute)
This is almost exactly what I want. It looks like this:
When I tried to implement the same in the non-admin website, I had to write quite a bit of code to do the inline formsets, form processing, in addition to the actual business logic. In addition to this, I faced the problem mentioned here.
I can't expose the admin interface to the end-user because we need to have a customized web design, and page flow. But, can I reuse parts of the admin interface code instead of re-implementing the same functionality?
Any other suggestions to reduce the code would be most welcome.
Django formset allows you to edit a collection of the same forms on the same page. It basically allows you to bulk edit a collection of objects at the same time.
One of the most powerful parts of Django is the automatic admin interface. It reads metadata from your models to provide a quick, model-centric interface where trusted users can manage content on your site. The admin's recommended use is limited to an organization's internal management tool.
Django's Admin is amazing. A built-in and fully functional interface that quickly gets in and allows data entry is priceless. Developers can focus on building additional functionality instead of creating dummy interfaces to interact with the database.
The Django admin application can use your models to automatically build a site area that you can use to create, view, update, and delete records. This can save you a lot of time during development, making it very easy to test your models and get a feel for whether you have the right data.
Here is the answer how to implement inline formsets like in Django admin http://kevindias.com/writing/django-class-based-views-multiple-inline-formsets/ However only CreateWiew is described. If you want to implement also UpdateView you need to do duplicate your code for it with a little tweaks
def get(self, request, *args, **kwargs):
"""
Handles GET requests and instantiates blank versions of the form
and its inline formsets.
"""
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
sample_form = SampleFormSet(instance=self.object)
return self.render_to_response(
self.get_context_data(form=form,
sample_form=sample_form))
def post(self, request, *args, **kwargs):
"""
Handles POST requests, instantiating a form instance and its inline
formsets with the passed POST variables and then checking them for
validity.
"""
self.object = self.get_object()
form_class = self.get_form_class()
form = self.get_form(form_class)
sample_form = SampleFormSet(self.request.POST, instance=self.object)
if (form.is_valid() and sample_form.is_valid()):
return self.form_valid(form, sample_form)
else:
return self.form_invalid(form, sample_form)
def form_valid(self, form, sample_form):
"""
Called if all forms are valid. Creates a Recipe instance along with
associated Ingredients and Instructions and then redirects to a
success page.
"""
self.object = form.save()
sample_form.save()
return HttpResponseRedirect(self.get_success_url())
and don`t forget to add DELETE formset field to your template
{% for form in sample_form %}
{{ form.id }}
<div class="inline {{ sample_form.prefix }}">
{{ form.description.errors }}
{{ form.description.label_tag }}
...
{{ form.DELETE }}
</div>
{% endfor %}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With