Django Admin modifications - python

I have an app in which two models are related with foreign keys.
class Trans(models.Model):
pk = UUIDField(auto=True, primary_key=True, serialize=True, hyphenate=True)
en = models.TextField('English')
class Article(models.Model):
pk = UUIDField(auto=True, primary_key=True, serialize=True, hyphenate=True)
title = models.OneToOneField(Trans)
description = models.OneToOneField(Trans)
Now if I want to add values in Article model via admin interface and for title and description there will be a '+' sign above the field to add values , on click Trans model form popup will shown where I can add values and then that instance will be attach into Article title field (Usual process).
But I do not want to add values like this , I want to show a simple text field to admin there for both title and description and on save those values saved into Trans model and their instance in Article model . In simple words I do not want to show '+' sign to admin but a simple text field.
Is this possible in Django admin if yes then any suggestions ?

Related

How to get dynamic choices field in admin panel of django- category sub-category

I have tried this a lot and searched about it too but not found any solution,
I want that in admin panel when admin selects the category choice field and the subcategory choice field changes according to it, like I have a category called 'Shoes' and 'watches' and sub-category accordingly for shoes - 'puma', 'Adidas' and watches-'titan', 'G-shock'. when admin selects category 'shoes' subcategory choices should be 'puma' and 'Adidas' and if he/she selects category 'watches' subcategory choices should be 'titan' and 'G-shock'.
here is my models.py
from django.db import models
from django.db import connection
# Create your models here.
class categorie(models.Model):
name = models.CharField(max_length=100, unique=True)
def __str__(self):
return self.name
class sub_categorie(models.Model):
sub_name = models.CharField(max_length=100)
catagory_name = models.ForeignKey(categorie, on_delete=models.CASCADE, default=1)
def __str__(self):
return self.sub_name
class Products(models.Model):
Product_Name = models.CharField(max_length=100)
price = models.FloatField()
Description = models.TextField()
ctg = models.ForeignKey(categorie, on_delete=models.CASCADE,blank = False, default=1)
sub_category = models.ForeignKey(sub_categorie, on_delete=models.CASCADE,blank = False)
Doing this is possible when you have UI control.
I would suggest first having your custom JS in the Admin Panel to Add Field and its choices based on the value of category field.
To add choices to the Admin Panel you can add choices attribute in your model field.
product_type = [('shoes','Shoes'),('watches','Watches')]
class categorie(models.Model):
name = models.CharField(max_length=100, unique=True,choices=product_type)
Now you need to add js to Admin Panel :How to load Custom JS in Django Admin Home
You can try this or a similar approach and check for the value of the field categorie in your JS and when it changes to lets say 'Shoes' then you need to add the field sub category with choices in select as 'Adidas,Puma,Nike,Reebok etc'.
UPDATE 1:
How to add custom JS in particular field:
When you have model in your app ,lets take the same categorie you have name as your field.You go to the ADMIN PANEL for this model, your field will have id as id_name as default.So your input will look something like.
<input type="text" name="name" class="vTextField" maxlength="100" id="id_name">
So you now have the id of your field in your admin forms.So for every fieldname you have id as id_fieldname.
You can add an Event Listener in JS for that field on value change.
document.getElementById('id_fieldname').addEventListener('change',function(){
#Do what you want here
});
So in that function either you can call another function that adds the select input field which have the required options or have the field already there and just insert options in the select field.

One-To-Many models and Django Admin

I have the following models:
#models.py
class Section(models.Model):
name = models.CharField(max_length=20)
class Tags(models.Model):
parent = models.ForeignKey(Section)
name = models.CharField(max_length=255, blank=True)
class Article(TimeStampedMode):
...
tag = models.ForeignKey(Tags)
In Django admin, tag shows up as a HTML <select multiple>.
What I'm trying to do is:
A Section could have many Tags, and from Article I could pick a Tags from Section.
Also, it needs to be able to get a Article's Section(via tags.parent?).
Currently this works. But, instead of <select multiple>, Tags shows up as a <input> instead of a <select multiple>.
What I want is for both Tags and Section appear as <select multiple>.
edit:
What I want is:
By using a foreign key to define the relationship, you're limiting the number of Tags an Article may have to 1. For an Article to have more than one Tag, you'll want to use a ManyToMany relationship.
Read more on many-to-many relationships with Django here: https://docs.djangoproject.com/en/dev/topics/db/examples/many_to_many/
The Django admin site will automatically use a select if you're using a foreign key relationship, or a multi-select if you're using a many-to-many relationship.
Here's what a many-to-many will look like from Article to Tags:
class Article(TimeStampedMode):
...
tag = models.ManyToManyField(Tags)
I don't understand your need correctly. But according to your image, you need Section and Tags are set One-To-Many field in Article.
#models.py
class Section(models.Model):
name = models.CharField(max_length=20)
class TagName(models.Model):
tag_name = models.CharField(max_length=255, blank=True)
class Tags(models.Model):
parent = models.ForeignKey(Section)
name = models.ForeignKey(TagName)
class Article(TimeStampedMode):
...
tag = models.ForeignKey(Tags)
I think this method is more useful and matching with your need.
screenshot of the given model code:
this is Article page
go into tag and you can see select multiple for both fields
Thank you

Adding Content to the Many to Many Field in Django

I am learning django and i am creating a simple Music Library which has 2 basic Models Song and Singer
Now a Singer has a many-to-many relationship with Song
Modles.py
class Singer(models.Model):
name = models.CharField('Singer', max_length=255)
class Song(models.Model):
title = models.CharField(max_length=255)
lyrics = models.TextField()
singer = models.ManyToManyField(Singer)
Now In my Admin Section i modified the singer (Multi Select) Field to Use the Select2 Jquery Plugin and I added the Tagging Support for this Plugin Using the code below :
$(".js-example-tags").select2({
tags: true
})
so i can type and add any new Singer's Name (who is not already Present) at the same time while adding the Song as i don't want a separate UI to add Singers Name.
Now I don't know how to proceed with adding this new Singer's Name to Singers Table and then relate him to the Specific Song in django-admin.
When i submit the form with any New Singer's Name, I get Validation Error. I have searched a lot but cannot seem to find any solution to this.
UPDATE
I tried to add a new Song from the Add Song Page in Admin Panel, In the Singer Field i specified "Some Singer" ( this singer is not present in my DB ). On submitting the form i get the error :
"Some SInger" is not a valid value for a primary key.
forms.py
class SongForm(forms.ModelForm):
class Meta:
model = Song
fields = ['title', 'lyrics', 'image', 'singer', 'pub_date']
widgets = {
'singer': forms.SelectMultiple(attrs={'class': 'multipleSelectBox'}),
}
admin.py
class SongAdmin(admin.ModelAdmin):
class Media:
def __init__(self):
pass
css = {
"all": ('css/plugins/select2.min.css', )
}
js = (
'http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js',
'js/plugins/select2.min.js',
'js/songs.js'
)
form = SongForm
admin.site.register(Song, SongAdmin)

Django admin search and edit foreign fields

I've got a two part question regarding Django Admin.
Firstly, I've got a Django model Classified that has a foreign key field from another table Address. On setting data, I've got no issues with any of the fields and all fields get saved correctly.
However, if I want to edit the foreign field in the entry in Classified, it doesn't display the old/existing data in the fields. Instead it shows empty fields in the popup that opens.
How do I get the fields to display the existing data on clicking the + so that I can edit the correct information?
Secondly, I'm sure I've seen search fields in Django Admin. Am I mistaken? Is there a way for me to implement search in the admin panel? I have over 2 million records which need to be updated deleted from time to time. It's very cumbersome to manually go through all the pages in the admin and delete or edit those.
Adding Model Code:
Classified
class Classified(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=256)
contact_person = models.CharField(max_length=300, blank=True)
email = models.CharField(max_length=100, blank=True)
address = models.ForeignKey(Address)
subcategory = models.ForeignKey(Subcategory)
Address
class Address(models.Model):
id = models.AutoField(primary_key=True)
build_add = models.CharField(max_length=255)
street_add = models.CharField(max_length=255)
area = models.CharField(max_length=255)
city = models.ForeignKey(Cities)
The + means just that - add a new instance of the related object and relate the object you're editing to that. Because you're adding a new object it will be blank to start. If you want to be able to edit existing related objects from another object's admin you need to use inlines.
In your app's admin.py have something like:
from django.contrib import admin
from yourapp.models import Address, Classified
class AddressInline(admin.TabularInline):
model = Address
class ClassifiedAdmin(admin.ModelAdmin):
inlines = [AddressInline,]
admin.site.register(Classified, ClassifiedAdmin)
Adding search from there is really easy.
...
class ClassifiedAdmin(admin.ModelAdmin):
inlines = [AddressInline,]
search_fields = [
'field_you_want_to_search',
'another_field',
'address__field_on_relation',
]
...
Note the double underscore in that last one. That means you can search based on values in related objects' fields.
EDIT: This answer is right in that your foreignkey relationship is the wrong way round to do it this way - with the models shown in your question Classified would be the inline and Address the primary model.

Django admin inline-model customization

Is there a way to de-couple django admin inline-models from clustering like models together?
A bit of context: I have a model named Page with two inline-models, TextBlock and GalleryContainer. I would to render TextBlocks and GalleryContainers on a template based on the order they're added in the Page admin editor. The default django-admin display looks like this:
I would like it to display as:
Gallery Container 1
Textblock 1
Gallery Container 2
But I have no idea how to do that. Any suggestions or nudges in the right direction would be a great help. Thanks in advance. (I also hope my question makes sense...)
If you want a relation between a column and a gallery your models should reflect that. So if I understand correctly: A page has name and columns. A column has text, gallery (optional) and ordering.
models.py:
class Page(models.Model):
name = models.CharField(max_length=200)
class Gallery(models.Model):
name = models.CharField(max_length=200)
class Column(models.Model):
page = models.ForeignKey(Page)
text = models.TextField()
gallery = models.ForeignKey(Gallery, null=True, blank=True) # Optional
ordering = models.IntegerField()
class Meta:
ordering = ('ordering', )
This example shows how ordering is done by an IntegerField. If you want to order the columns based on the moment they where added replace
ordering = models.IntegerField()
with
models.datetimeField(auto_now_add=True)
In your admin.py:
class ColumnInline(admin.TabularInline): # or StackedInline
model = Column
class PageAdmin(admin.ModelAdmin):
inlines = [
ColumnInline,
]
Note: I put your 'gallery display name' in Gallery as 'name'. Makes more sense to give the gallery it's name only once. But if a gallery is in more places with different names, than you need a field (e.g. 'gallery_display_name=models.CharField(max_lenght=200)') on the Column model.
Is this the answer to your question? I hope it helps!

Categories

Resources