How to make Django admin shows OneToMany instead of ForeignKey - python

In Django admin page when we use a ForeignKey in a object, the admin shows the option to set a ForeignObject in the model that has the ForeignKey value.
For example:
class Diferencial(SobreFather):
class Meta:
verbose_name = 'Diferencial'
verbose_name_plural = 'Diferenciais'
class DiferencialItem(models.Model):
diferencial = models.ForeignKey(Diferencial)
icone = models.ImageField(upload_to="icones_diferencial")
texto = models.CharField(max_length=50, null=False, blank=False)
def __unicode__(self):
return self.diferencial
class Meta:
verbose_name = 'Item Diferencial'
verbose_name_plural = 'Itens Diferencial'
This code will show the option to select a Diferencial object to be related to DiferencialItem in django admin.
Is there a way to show the option to create the DiferencialItem in the Diferencial admin view?

Yes, use the inline model admin:
class DiferencialItemInline(admin.TabularInline):
model = DiferencialItem
class DiferencialAdmin(admin.ModelAdmin):
inlines = [DiferencialItemInline]

Related

How to connect 2 many to many fields in Django

I have 2 many to many fields in models and i want to connect them to each other i mean if i connect user in Admin Model with Counter Party i cant see that in Counter Party admin
How can i do that?
When im trying to do that it shows only in 1 model
models.py
class CustomUser(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, verbose_name='Пользователь')
user_counter = models.ManyToManyField('CounterParty', blank=True, verbose_name='Контрагенты пользователя')
def __str__(self):
return f'{self.user}'
class CounterParty(models.Model):
GUID = models.UUIDField(default=uuid.uuid4, editable=True, unique=True)
name = models.CharField(max_length=150, verbose_name='Наименование')
customer = models.BooleanField(default=False, verbose_name='Заказчик')
contractor = models.BooleanField(default=False, verbose_name='Подрядчик')
counter_user = models.ManyToManyField(User, blank=True, related_name='counter_user',
verbose_name='Пользователи контрагента')
class Meta:
verbose_name = 'Контрагент'
verbose_name_plural = 'Контрагенты'
def __str__(self):
return
admin.py
from django.contrib import admin
from .models import CustomUser, CounterParty, ObjectList, SectionList
from authentication.models import User
from authentication.admin import UserAdmin
class CustomUserInLine(admin.StackedInline):
model = CustomUser
can_delete = False
verbose_name_plural = 'Пользователи'
class CustomUserAdmin(UserAdmin):
inlines = (CustomUserInLine,)
#admin.register(CounterParty)
class CounterPartyAdmin(admin.ModelAdmin):
pass
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
user admin
counter party admin
You would not want to have these kinds of references with ManyToMany. Ideally you would have a one sided reference.
You can do an inline in your admin like this:
class CustomUserInLine(admin.StackedInline):
model = "CustomUser.user_counter.through"
Here are the docs for inline M2M in the admin: Django docs

Sort a displayed column defined by a custom model method in the Django admin interface

I want to be able to sort a table column defined using a custom method in the Django admin.
I narrowed down the problem to this simple example in Django:
models.py:
from django.db import models
class MyObject(models.Model):
name = models.CharField(_("name"), max_length=255)
layers = models.URLField(_("Layers"), blank=True, max_length=1024)
choices = models.TextField(
verbose_name=_("Choice values"),
blank=True,
help_text=_("Enter your choice"),
)
class Meta:
verbose_name = _("Object config")
verbose_name_plural = _("Objects config")
def __str__(self): # my custom method
return self.name
and admin.py:
from django import forms
from django.contrib import admin
class MyObjectAdminForm(forms.ModelForm):
"""Form"""
class Meta:
model = models.MyObject
fields = "__all__"
help_texts = {
"layers": "URL for the layers",
}
class MyObjectAdmin(admin.ModelAdmin):
form = MyObjectAdminForm
list_filter = ["name",]
search_fields = ["name",]
# I want the first column (__str__) to be sortable in the admin interface:
list_display = ["__str__", ...] # the ... represent some other DB fields
but for the moment I cannot sort that first column (it is grayed out, I cannot click on its title):
So how could I sort the first column in this admin table as defined by the __str__() method of the MyObject model? (please note that I cannot change the model itself. I'm also brand new to Django, so don't hesitate to detail your answer as if you were speaking to a kid.)

How can I create form using this django model?

I am trying to create form using this model. I want to add data in this database model using form to perform CRUD operation. I am using MySQL database.
models.py
from django.db import models
from .managers import CategoryManager, SubCategoryManager
# this is my parent model
class Node(models.Model):
name = models.CharField(max_length=150)
parent = models.ForeignKey(
'self',
on_delete=models.CASCADE,
related_name='children',
null=True,
blank=True
)
def __str__(self):
return self.name
class Meta:
ordering = ('name',)
verbose_name_plural = 'Nodes'
class Category(Node):
object = CategoryManager()
class Meta:
proxy = True
verbose_name_plural = 'Categories'
class SubCategory(Node):
object = SubCategoryManager()
class Meta:
proxy = True
verbose_name_plural = 'SubCategories'
class Product(models.Model):
sub_category = models.ForeignKey(
SubCategory, on_delete=models.CASCADE
)
name = models.CharField(max_length=100)
description = models.TextField(blank=True)
def __str__(self):
return self.name
Try the Imagine smart compiler which allows automatic generating of code + tests for your CRUD APIs and Django models from a very simple config. Amongst other things, it generates code in the correct way to handle foreign key relationships in Django Views. You can also try a demo here imagine.ai/demo
PS: Something like this simple config will generate all the code for the CRUD API along with the tests!
Model Node {
id integer [primary-key]
name string [max-length 150]
}
Model Product {
id integer [primary-key]
name string [max-length 100]
description string [nullable]
}

Django admin form, field instead of object in foreign key

Im using a forigen key to reference another object from my parent object. However when i go to the drop down list created by django admin, i get the object name instead of the field value. how can i add the field value to the form instead?
admin.py
from django.contrib import admin
from .models import Maintenance
from .models import MaintenanceType
from .models import ServiceType
# Register your models here.
class MaintenanceAdmin(admin.ModelAdmin):
list_display = ('Title','Impact','Service','Description','StartTime','EndTime',)
list_editable = ('Title','Impact','Service','Description','StartTime','EndTime',)
admin.site.register(Maintenance, MaintenanceAdmin)
class MaintenanceTypeAdmin(admin.ModelAdmin):
list_display = ('Type',)
list_editable = ('Type',)
admin.site.register(MaintenanceType, MaintenanceTypeAdmin)
class ServiceTypeAdmin(admin.ModelAdmin):
list_display = ('Service','Service',)
list_editable = ('Service','Service',)
admin.site.register(ServiceType, ServiceTypeAdmin)
models.py
from django.db import models
# Create your models here.
class MaintenanceType(models.Model):
Type = models.CharField(max_length=200)
class Meta:
verbose_name = "Planned Maintenance Types"
verbose_name_plural = "Planned Maintenance Types"
class ServiceType(models.Model):
Service = models.CharField(max_length=200)
class Meta:
verbose_name = "Service Types"
verbose_name_plural = "Service Types"
class Maintenance(models.Model):
Title = models.CharField(max_length=200)
Impact = models.ForeignKey(MaintenanceType)
Service = models.ForeignKey(ServiceType)
Description = models.TextField()
StartTime = models.DateTimeField()
EndTime = models.DateTimeField()
class Meta:
verbose_name = "Planned IT Maintenance"
verbose_name_plural = "Planned IT Maintenance"
Implement __str__ in the MaintenanceType model, which should return a string in whatever formatting you wish to appear in the drop down (and anywhere else actually).
It appears that you simply need to return self.Type.
Python 2 only
You can specify what's returned by accessing an object by setting the unicode method to retun what you want it to be.
So I think your MaintenanceType should look like
class MaintenanceType(models.Model):
Type = models.CharField(max_length=200)
class Meta:
verbose_name = "Planned Maintenance Types"
verbose_name_plural = "Planned Maintenance Types"
def __unicode__(self):
return self.Type

Overriding formset in TabularInline Django admin form

I'm having trouble overriding the formset on a TabularInline inline of a ModelAdmin object in my admin site. I know you're supposed to have a model associated with a TabularInline object, but I'm not sure how to specify this on the form object used to generate the formset. With the code below, I'm getting "'AppAssetInline.formset' does not inherit from BaseModelFormSet."
class AppAssetForm(forms.ModelForm):
model = App.assets.through
primary = forms.BooleanField()
uuid = forms.CharField()
class AppAssetInline(admin.TabularInline):
model = App.assets.through
AssetFormset = formset_factory(AppAssetForm)
formset = AssetFormset
class AppAdmin(admin.ModelAdmin):
inlines = [AppAssetInline,]
The answer to my question didn't have to do with how I was structuring my forms, but rather how I was joining fields on my models. I had the following structure in my models:
class App(models.Model):
package = models.FileField(upload_to=settings.APP_PACKAGE_ROOT)
assets = models.ManyToManyField('AppAsset', blank=True, null=True)
download_count = models.IntegerField(default=0)
class AppAsset(models.Model):
def __unicode__(self):
return self.asset_file.name
notes = models.CharField(max_length=255, null=True, blank=True)
type = models.CharField(max_length=255, null=True, blank=True)
asset_file = models.FileField(upload_to=settings.APP_PACKAGE_ROOT)
What I did was change the structure such that AppAsset now has a foreign key on App for its assets. After that, I could use the TabularInline on the AppAsset model with no problems. Here are the latest source files:
https://github.com/ridecharge/spout/blob/master/Spout/AppDistribution/models.py
https://github.com/ridecharge/spout/blob/master/Spout/AppDistribution/admin.py
You should use django.forms.models.inlineformset_factory instead of formset_factory

Categories

Resources