I have a website built in Django 1.10. The site has 3 different apps: teams, members and news.
The first app, called teams has one model called Team.
This is the Team/models.py:
from django.db import models
from django.db.models.signals import pre_save
from django.utils.text import slugify
class Team(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
slug = models.CharField(max_length=255, default='team', editable=True)
class Meta:
ordering = ('name',)
def __unicode__(self):
return self.name
The second app, called members has one model called Member.
This is the Member/models.py:
from django.db import models
class Piloto(models.Model):
name = models.CharField(max_length=255)
biography = models.TextField()
slug = models.CharField(max_length=255, default='piloto', editable=True)
class Meta:
ordering = ('name',)
def __unicode__(self):
return self.name
What I want is include the name of the team inside the member profile, so I know it should be something like:
team_of_member = models.ForeignKey();
But I don't know what to put in the parenthesis or how to import the model of the team to the model of the member. I was following the documentation of Django 1.10 but it wasn't working, also I've tried this link but it doesn't work. Could you give a hand? Thanks
Edit:
I tried to do as #Bulva was suggesting, so my code is now like this:
from django.db import models
from equipos.models import Team
class Member(models.Model):
name = models.CharField(max_length=255)
team = models.ForeignKey('teams.Team', null=True)
biography = models.TextField()
slug = models.CharField(max_length=255, default='piloto', editable=True)
class Meta:
ordering = ('name',)
def __unicode__(self):
return self.name
What you want is to provide the teams the member is a member of. It all depends on your business logic. A team has many members by definition, but can a member be a part of many teams? If yes, you have a many-to-many relationship. If no, you have a one-to-many relationship.
Under one-to-many assumption, the foreignkey information has to be put in the referenced model. Then:
from django.db import models
from team.models import Team # Generally, apps are in all lower-case (assuming your app is called team)
class Member(models.Model):
name = models.CharField(max_length=255)
team = models.ForeignKey('team.Team', related_name = 'members', null=True) # Do not forget to put team.Team inside a pair of single-quotes.
biography = models.TextField()
slug = models.CharField(max_length=255, default='piloto', editable=True)
class Meta:
ordering = ('name',)
def __unicode__(self): # use def __str__(self): in Python 3+
return self.name
In your view, you can then say this:
albert_team = albert.team
albert_teammates = albert_team.members
Under Many-to-Many assumption, it is more natural to capture the relationship in the team model:
from django.db import models
from django.db.models.signals import pre_save
from django.utils.text import slugify
class Team(models.Model):
name = models.CharField(max_length=255)
description = models.TextField()
slug = models.CharField(max_length=255, default='team', editable=True)
members = models.ManyToManyField('team.Member', related_name = 'teams')
class Meta:
ordering = ('name',)
def __unicode__(self):
return self.name
In views.py:
albert_teams = albert.teams
all_albert_teammates = []
for team in albert_teams:
all_albert_teammates.append(team.members)
Try this:
from teams.models import Team
# in the member model field
team_of_member = models.ForeignKey(Team);
In order to do what you want (assuming the code provided is your full "problematic" code) you should:
In Member/models.py:
from django.db import models
from teams.models import Team # <--add this line
class Piloto(models.Model):
name = models.CharField(max_length=255)
team_of_member = models.ForeignKey(Team, on_delete=models.CASCADE); # <--add this line
biography = models.TextField()
slug = models.CharField(max_length=255, default='piloto', editable=True)
class Meta:
ordering = ('name',)
def __unicode__(self):
return self.name
After you do this, remember to:
python manage.py makemigrations
python manage.py migrate
to change your models state.
Good luck :)
Related
models.py
from django.db import models
from django.contrib.auth.models import User
STATUS = (
(0,"Draft"),
(1,"Publish")
)
class BlogModel(models.Model):
id = models.AutoField(primary_key=True)
blog_title = models.CharField(max_length=200)
blog = models.TextField()
status = models.IntegerField(choices=STATUS, default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_at']
def __str__(self):
return f"Blog: {self.blog_title}"
class CommentModel(models.Model):
your_name = models.CharField(max_length=20)
comment_text = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
blog = models.ForeignKey('BlogModel', on_delete=models.CASCADE)
class Meta:
ordering = ['-created_at']
def __str__(self):
return f"Comment by Name: {self.your_name}"
admin.py
from django.contrib import admin
from blog.models import BlogModel,CommentModel
class PostAdmin(admin.ModelAdmin):
list_display = ('blog_title', 'status','created_at','updated_at')
list_filter = ('status',)
search_fields = ('blog_title', 'content',)
admin.site.register(BlogModel, PostAdmin)
admin.site.register(CommentModel)
I created a simple blog post website with comments and I want to create reports and on the admin panel I have to see how to achieve this.
Like how many posts are created and how many have comments and how many post are draft and published
I checked this module but I don't understand how to implement it https://pypi.org/project/django-reports-admin/
You already have most of this, by using PostAdmin. The list_display already shows you how many posts are published/draft, and the change list has filters for that as well.
To show the comment count, simply add that to list_display:
class PostAdmin(admin.ModelAdmin):
list_display = ('blog_title', 'status', 'comment_count', 'created_at', 'updated_at')
def comment_count(self, obj):
return obj.commentmodel_set.count()
comment_count.short_description = 'Comment count'
This thus defines a custom method on the PostAdmin, that displays the comment count as a column, and gives it a user-friendly name as column header.
You can expand this with more statistics if you like. The Django admin is highly customizable.
Note: model names should be in CamelCase, so BlogModel and CommentModel should be Blog and Comment respectively.
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]
}
I have nested models with OneToOneFields and want to have an InlineModelAdmin form in one ModelAdmin to point to a nested model...
models.py:
class User(models.Model):
username = models.CharField(max_length=128)
password = models.charField(max_length=128)
class IdentityProof(models.Model):
user = models.OneToOneField(User, on_delete=models.PROTECT, related_name='proof')
proof_identity = models.FileField(upload_to='uploads/%Y/%m/%d/')
class Company(models.Model):
user = models.OneToOneField(User, on_delete=models.PROTECT, related_name='company')
name = models.CharField(max_length=128)
class Person(models.Model):
user = models.OneToOneField(User, on_delete=models.PROTECT, related_name='person')
name = models.CharField(max_length=128)
admin.py:
class IdentityProofInline(admin.TabularInline):
model = IdentityProof
#admin.register(Company)
class CompanyAdmin(admin.ModelAdmin):
inlines = [IdentityProofInline]
#admin.register(Person)
class PersonAdmin(admin.ModelAdmin):
inlines = [IdentityProofInline]
For CompanyAdmin or PersonAdmin, I want to show its User's IdentityProof. How can I do that ?
I tried to use fk_name = 'user_proof or other combinations but it doesn't work...
Thanks.
This is not possible without an external package.
See Django Nested Inline and Django Nested Admin
I am using python version 3.5 and django version 1.11.
I wanted to know what field should I use for pasword
models.py
from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import User
class Employee(models.Model):
name = models.CharField(max_length=50,null=True)
username = models.CharField(max_length=100,null=True)
password = models.CharField(max_length=128)
repeat_password = models.CharField(max_length=128)
email = models.EmailField(max_length=70,null=True)
phone_number = models.IntegerField(default=0)
permanent_address = models.CharField(max_length=100,null=True)
alternative_address = models.CharField(max_length=100,null=True)
salary = models.IntegerField(default=0)
join_date = models.DateField(null=True)
paid_salary_date = models.DateField(null=True)
designation = models.CharField(max_length=50,null=True)
def __str__(self):
return self.name
Don't reinvent the wheel, extend the Django User model instead, and add those extra fields to your Employee class. You can equally override or define new methods.
See Extending the existing User model. Infact, the example provided in the docs is an Employee class.
from django.contrib.auth.models import User
class Employee(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
department = models.CharField(max_length=100)
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