Edit manytomany field right from Admin form for model - django

I have models like below
class Product(models.Model):
...
class ProductQuantity(models.Model):
product = models.ForeignKey('Product')
invoice = models.ForeignKey('Invoice')
quantity = models.IntegerField()
class Invoice(models.Model):
...
products = models.ManyToManyField(Product, through=ProductQuantity)
In django admin I would like to change quantity not by opening new dialog, which is basically how admin behaves, instead selecting one of them if any, or type there and change values directly from that window.

You can use an inline:
class ProductQuantityInline(admin.StackedInline):
model = ProductQuantity
class InvoiceAdmin(admin.ModelAdmin):
inlines = [ProductQuantityInline]
That way, you can edit the ProductQuantity directly on the Invoice admin page, without any extra dialogs.

Related

When adding a record in Django admin, when a field is selected, I want the other field to come automatically depending on it

In order to make the problem easier to understand, I am writing the codes as short as possible here.
models.py:
----------
class Room(models.Model):
room_no = models.CharField()
class Unit(models.Model):
unit_name = models.CharField()
room = models.ManyToManyField(Room, related_name='roomunit')
class Employee(models.Model):
employee_name = models.CharField()
unit = models.ForeignKey(Unit)
room = models.ForeignKey(Room)
admin.py:
---------
class EmployeeAdmin(admin.ModelAdmin):
list_display('employee_name', 'unit', 'room',)
class RoomAdmin(admin.ModelAdmin):
list_display=('room_no',)
class UnitAdmin(admin.ModelAdmin):
list_display=('unit_name', 'roomno',)
def roomno(self,obj):
r = Room.objects.get(roomunit=obj)
return r
admin.site.register(Employee, EmployeeAdmin)
admin.site.register(Unit, UnitAdmin)
admin.site.register(Room, RoomAdmin)
Sample data were entered for the room and the unit according to the relationship between them.
There is ManyToMany relation between Unit and Room.
Screenshot of Employee add form.
Screenshot of the form
This is what i want to do:
When adding a new employee to the employee add form, when I select the unit name, I want the room_no associated with it to appear automatically

Django admin: filter_horizontal with custom search/filter results

I have a simple model with ManyToManyField.
class Meeting(models.Model):
place = models.CharField()
date = models.DateField()
persons = models.ManyToManyField(Person)
Person model contains basic information about person.
class Person(models.Model):
login = models.CharField(unique=True)
first_name = models.CharField()
last_name = models.CharField()
def __str__(self):
return self.login
In my MeetingAdmin(ModelAdmin) class I have filter_horizontal('persons',) that is used for adding multiple people when creating new Meeting object. This works perfectly fine. In the left menu it's showing the list of all persons(filtering by login).
As you may know, filter_horizontal contains search box on the top of the left menu.
Examples
I would also like to be able to filter persons here by their first name and last name. For example, if there is a person with fields (login='mylogin', first_name='John', last_name='Smith') and I type 'Jo' or 'Smi' in search box, this person is displayed as a search result, etc. 'mylogin' since login field is representation of Person model.

Trouble displaying inline forms of a ModelAdmin

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.

How to add\get data in admin via reversed relation using GenericTabularInline?

I can add Criterias to a place. How can I add Places to a criteria?
Models:
class Criterias(models.Model):
name = ...
class Places(models.Model):
name = ...
class PlacesToCriterias(models.Model):
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
criteria_group = models.ForeignKey(Criterias)
Admin - PLACES part:
class PlaceCriteriasInlineAdmin(GenericTabularInline):
model = PlacesToCriterias
class PlacesAdmin(admin.ModelAdmin):
inlines = [PlaceCriteriasInlineAdmin]
admin.site.register(Places, PlacesAdmin)
In this case, when I open Places admin change page, I can add Criterias items to my 'place'.
Admin - CRITERIAS part:
class CriteriaPlacesInlineAdmin(GenericTabularInline):
model = PlacesToCriterias
class CriteriasAdmin(admin.ModelAdmin):
inlines = [CriteriaPlacesInlineAdmin]
admin.site.register(Criterias, CriteriasAdmin)
In this case, when I open Criterias admin change page, I CAN NOT add Places item to my 'criteria', because instead of possible places I see criterias.
How to get Places items at Criterias admin page?
It was quite easy. GenericTabularInline must be changed to admin.TabularInline
class CriteriaPlacesInlineAdmin(admin.TabularInline):
model = PlacesToCriterias
class CriteriasAdmin(admin.ModelAdmin):
inlines = [CriteriaPlacesInlineAdmin]
admin.site.register(Criterias, CriteriasAdmin)
If anyone needs to get dropdown list with selected object, instead of content_type and object_id fields, the solution is here.

django populate admin listbox field from another model

I have a model field in which staff users can select a value from a list box. I used a fix list and the "choiches" parameter.
class Exercise(models.Model):
member = models.ForeignKey(Member)
name = models.CharField(max_length=50, choices=EXERCISES_LIST)
where EXERCISE_LIST is a sequence of tuple as required by "choiches" parameter.
Now I would like to give staff users the possibility to create this EXERCISES_LIST by themself using a model, is it possibile? and what happen if they delete an item from the list that is used by a Exercise model record?
here is the solution:
I created another model in models.py only for the name of the exercise:
class ExerciseName(models.Model):
name = models.CharField(max_length=50)
def __str__(self):
return u'%s' % (self.name)
I modified the original model adding a ForeignKey to ExerciseName
class Exercise(models.Model):
member = models.ForeignKey(Member)
name = models.ForeignKey(ExerciseName)
I registered ExerciseName model in admin.py to have the possibility to modify them in a separate admin view.
admin.site.register(ExerciseName)
So now I'm able to create a new Exercise and to choose its name from another model (ExerciseName).