I'm new to Django so this might be a simple question. I'm trying to build a portfolio site using Django. I'd like to have a homepage, portfolio page, portfolio detail pages, and contact page. There will be about 20 portfolio detail pages - Project A, Project B, Project C. Each project (portfolio detail page) has multiple areas where I can input text that is populated through the Django admin. How do I create custom fields in the admin for each Portfolio Detail page (headline, project name, url, description) and display them in the page template?
I'm confused as do I use the pages section in the Django admin and add custom fields for each page or do I create a custom app with these custom fields? Then let's say Project B needs an extra field for awards. How do I add that custom field for just the Project B page in the Django admin?
There is no reason why you can't add any number of fields to your project by just linking them with foreign keys.
project/models.py
from django.db import models
class Project(models.model):
name = models.CharField(max_length=100)
class ProjectField(models.model):
project = models.ForeignKey(Project)
fieldname = models.CharField(max_length=50)
value = models.TextField(max_length=2000)
With what you are describing, it sounds like you would like to edit the ProjectField values in the Project admin page. The way that the admin page handles that normally is with inlines.
As an example for the models above:
projects/admin.py
from projects import models
from django.contrib import admin
class ProjectFieldInline(admin.StackedInline):
model = models.ProjectField
extra = 0
class ProjectAdmin(admin.ModelAdmin):
inlines = [ProjectFieldInline]
admin.site.register(models.Project, ProjectAdmin)
I can't say one hundred percent that this will work for what you are asking, but I recomend giving the app above a try and seeing how close it is to what you want.
Related
I have a Django project that includes a model class with an optional self-referential ForeignKey field. A partial snippet:
class Site(models.model):
name = models.CharField(max_length=100)
parent_site = models.ForeignKey('self', null=True, blank=True)
I'm using the Django admin site to create new objects. For this class' admin form I'd like to disable the "Add another..." button next to the parent_site field (i.e. when you're creating a new site, you can't open the popup to create another new site as the parent).
I can't remove has_add_permission from the user, as they need it to be in the current add view. I don't mind removing the function from both add and change views, but limiting removal to the add view would be helpful.
I haven't been able to work out how to use the Inline field classes to achieve this, or formfield_for_foreignkey, or a custom ModelForm. Anyone got a solution more elegant than using JavaScript on a customised form template?
no css hacks add to admin class:
max_num=0
or try this in admin.py ( for older django versions):
class MODEL_ADMIN(admin.ModelAdmin):
class Media:
css = {'all': ('css/no-addanother-button.css',)}
First the simplified scenario:
from django.db import models
class Product(models.Model):
name = models.TextField()
description = models.TextField()
class Merchant(models.Model):
name = models.TextField()
class MerchantProductMapping(models.Model):
merchant = models.ForeignKey(Merchant)
product = models.ForeignKey(Product)
price = models.IntegerField()
inventory_limit = models.IntegerField()
I have another model for the relation (MerchantProductMapping) because the relation has attributes of its own. Now the requirements of the Merchant and the Product model have grown to a point where they demand separate apps of their own. The merchant app's models.py is where the Merchant model will live and the product app's models.py is where the Product model will live.
What I need help with is the relation model MerchantProductMapping. It is needed by both apps, where should I put it ? I've been reading up on mixins and wondering if they could help me somehow.
EDIT: I should add that the app was rendered server side earlier. Now it will be done using angular client - REST api approach. And django rest framework will be used on top of django.
Create "common" app for such purposes ... you can put there decorators, templatetags, base forms, base models, login|logout redirect views and urls, ajax views, base filters, base tables ... etc
Note: create "apps" python package dir (dir with __init__.py inside it) and (refactor) move all your apps there.
EDIT:
Another way - create "models" python package dir and split your models.py to logically separated files inside package
How to implement Dashboard in django admin?
If I have following Model in django. Is there a way, instead of regular Models list,I can have a search box in admin page to search for student using his name and display his particular details...
class MStudent(models.Model):
enroll_no = models.IntegerField()
Name = models.CharField(max_length=200)
photo = models.ImageField(upload_to="static",blank = True)
def __str__(self):
return self.FName+" "+ self.MName+" "+ self.LName
class MStud_Address_ph_no_email(models.Model):
enroll_no = models.ForeignKey(MStudent)
Address = models.CharField(max_length=200)
Personal_mobile= models.IntegerField()
Fathers_mobile = models.IntegerField()
def __str__(self):
return str(self.enroll_no)
From the Django admin documentation:
If you wish to change the index, login or logout templates, you are better off creating your own AdminSite instance (see below), and changing the AdminSite.index_template , AdminSite.login_template or AdminSite.logout_template properties.
So you should create your own AdminSite and set its index_template attribute to a template of yours that implements the Dashboard you want.
To provide a search and a search results view, see adding views to admin sites.
I think you should read the django docs about admin
And in your case if you want to customize the admin look and feel or adding extra fucntionality, you need override the required admin templates like admin/index.html by creating an admin folder in your template directory
Q.Is there a way, instead of regular Models list, I can have a search box in admin page to search for student using his name and display his particular details?
1) Yes Instead of displaying regular Models list I can directly redirect to model Mstudent.using following code
urls.py
from django.http import HttpResponseRedirect
url(r'^admin/$',lambda x:HttpResponseRedirect('/admin/yourapp/yourmodel'))
2) To search for student using his name and display his particular details:
Make MStud_Address_ph_no_email as inline to MStudent in admin.py.
So all in all whenever a user logged in to django admin, He will directly see list of all students and by selecting a particular student he can see all his details.
:)
I know this issue has been asked more than once, but as Django is evolving with new version, I'll ask the question again :
I am using the model User (Django User, not in my models.py) and create another model with a Foreign key to User.
models.py :
class Plan(models.Model):
user = models.ForeignKey(User)
I can simply display every Plan in my user by doing this in admin.py :
class PlanInline(admin.TabularInline):
model = Plan
extra = 0
class MyUserAdmin(UserAdmin):
ordering = ('-date_joined', 'username')
inlines = [PlanInline,]
admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)
But things are about to get more tricky. I want to add a model that has a foreign key pointing to Plan :
class Order(models.Model):
plan = models.ForeignKey('Plan')
And I want to be able to see all Orders for each Plan. As of today, it is impossible to have nested inlines in Django Admin (without editing the HTML, which I want to avoid) :
User
-> Plan 1
-> Order 1
-> Order 2
-> Plan 2
-> Order 3
So my idea is to display in the User Admin only A LINK for each plan, to the page to edit Plans, and put Orders as inline :
class OrderInline(admin.TabularInline):
model = Order
extra = 0
class PlanAdmin(admin.ModelAdmin):
inlines = [OrderInline,]
admin.site.register(Plan, PlanAdmin)
The question is, how do I display a link to a Plan in my User Admin?
class MyUserAdmin(UserAdmin):
ordering = ('-date_joined', 'username')
??? LINK ????
I saw some solutions on this topic : Django InlineModelAdmin: Show partially an inline model and link to the complete model, but they are a bit "dirty' as they make us write HTML and absolute path into the code.
Then I saw this ticket on Djangoproject : https://code.djangoproject.com/ticket/13163. It seems exactly what I'm looking for, and the ticket is "fixed". So I tried adding like in the fix show_change_link = True :
class PlanInline(admin.TabularInline):
model = Plan
extra = 0
show_change_link = True
class MyUserAdmin(UserAdmin):
ordering = ('-date_joined', 'username')
show_change_link = True
inlines = [UserProfileInline, PlanInline]
But it doesn't work (and I have no log or error).
Is there any way to do this in a clean way?
Update for django 1.8
show_change_link = True
https://github.com/django/django/pull/2957/files
I suggest adding a custom PlanInline method that returns the link and see if it helps. Something along these lines:
from django.utils.safestring import mark_safe
from django.core.urlresolvers import reverse
class PlanInline(TabularInline):
model = Plan
readonly_fields = ('change_link',)
...other options here...
def change_link(self, obj):
return mark_safe('Full edit' % \
reverse('admin:myapp_plan_change',
args=(obj.id,)))
Basically all we do here is create the custom method that returns a link to the change page (this specific implementation is not tested, sorry if there is any parse error but you get the idea) and then add it to the readonly_fields as described here: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.readonly_fields
A couple of notes for the change_link method: You need to replace 'myapp' in the view name with your actual application name. The mark_safe method just marks the text as safe for the template engine to render it as html.
So I've set up my django site with the following admin.py:
import models
from django.contrib import admin
admin.site.register(models.Comment)
which uses this models.py:
from django.db import models
class Comment(models.Model):
text = models.CharField(max_length=400)
name = models.CharField(max_length=100)
date = models.DateTimeField(auto_now = True)
article = models.CharField(max_length=100)
However, when I go to the admin page, it shows the following:
Which generally is not very helpful. Clicking on each link gives me a page with that object's data, but I would like to be able to see the information for each object in this view. I've been looking at the ModelAdmin class at:
https://docs.djangoproject.com/en/dev/ref/contrib/admin/
but have not managed to wrap my head around it. Is it a separate model class that needs to be kept in sync with my "actual" model? Is it just an interface through which my Admin site accesses the actual model? Does it do what I want (allowing useful data to be shown in the admin interface) or does it do something else?
I'm thinking that the Django Admin page should be able to replace PHPMyAdmin for doing simple tasks, like browsing the DB and manually modifying individual objects. Is that the case?
The admin turns your object into a string so just put a def __str__ or def __unicode__
(As #Mandax has reminded me the docs recommend to define __unicode__ only.)
def __unicode__(self);
return u"%s (%s): %s" % (self.article, self.date, self.name)
Just as it says in the documentation, your model's ModelAdmin describes how the admin section will represent your model. It does need to be somewhat in sync with the actual model, it doesn't make sense for you to display fields that aren't present on your model, etc. You seem interested in the changelist view, which has numerous customization options (all described in the documentation, and in the tutorial). A simple start might be:
from django.contrib import admin
class CommentAdmin(admin.ModelAdmin):
# define which columns displayed in changelist
list_display = ('text', 'name', 'date', 'article')
# add filtering by date
list_filter = ('date',)
# add search field
search_fields = ['text', 'article']
admin.site.register(Comment, CommentAdmin)
There are a lot of options for customization, as always refer to the docs! Finally, you could certainly use it in lieu of PHPMyAdmin, it's very easy to setup admin for browsing, modifying object, etc, how much use you get out of it is up to you.