Field related to field of related object Django - django

How can i make field related to field of related model. I have two models: album and photo, album model have boolean field private. How to create field private in photo, which will have False value if album field equal to None and value of album private field if it's not.
models.py:
from django.db import models
from django.contrib.auth.models import User
import os
import uuid
def get_image_path(instance, filename):
return '{}.{}'.format(uuid.uuid4(), filename.split('.')[-1])
class Album(models.Model):
user = models.ForeignKey(User, related_name='albums', on_delete=models.CASCADE)
title = models.CharField(max_length=80, default='New album')
creation_date = models.DateField(auto_now_add=True)
private = models.BooleanField(default=False)
def __str__(self):
return self.title
class Meta:
ordering = ['-creation_date', ]
class Photo(models.Model):
user = models.ForeignKey(User, related_name='photos', on_delete=models.CASCADE)
album = models.ForeignKey(Album, related_name='photos', on_delete=models.CASCADE, null=True, blank=True)
title = models.CharField(max_length=80, default='New photo')
image = models.ImageField(title, upload_to=get_image_path)
creation_date = models.DateField(auto_now_add=True)
# ???
private = models.BooleanField()
# ???
def __str__(self):
return self.title
class Meta:
ordering = ['-creation_date', ]

As #RodXavier said just use property
class Photo(models.Model):
user = models.ForeignKey(User, related_name='photos', on_delete=models.CASCADE)
album = models.ForeignKey(Album, related_name='photos', on_delete=models.CASCADE, null=True, blank=True)
title = models.CharField(max_length=80, default='New photo')
image = models.ImageField(title, upload_to=get_image_path)
creation_date = models.DateField(auto_now_add=True)
#property
def private(self):
return getattr(self, 'album', False)

Related

How to display all child category from parent category in django-rest-framework

I'm trying to show my all children category from parent category. I want to just hit one API end and show all tables which is related to that item. I want to hit "Master-Category" and show all releated "Category","Sub-Category" and "Root-Item" in Hierarchy form. I display all the data but cannot in Hierarchy form. Can anyone please give me the solution for this problem.
Model.py
from django.db import models
from django.contrib.auth.models import User
class MasterCategory(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True,
verbose_name="Created By")
title = models.CharField(max_length=100, null=False, blank=False)
description = models.TextField(default='')
def __str__(self):
return str(self.title)
#property
def category(self):
data = NewCategory.objects.filter(master_category__id=self.id).values
return data
#property
def sub_category(self):
data = NewSubcategory.objects.filter(category__id=self.id).values
return data
#property
def root_item(self):
data = Rootitem.objects.filter(sub_category__id=self.id).values
return data
class NewCategory(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True,
verbose_name="Created By")
title = models.CharField(max_length=100, null=False, blank=False)
description = models.TextField(default="")
master_category = models.ForeignKey(
MasterCategory, on_delete=models.CASCADE, null=True, blank=True)
def __str__(self):
return str(self.title)
class NewSubcategory(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True,
verbose_name="Created By")
title = models.CharField(max_length=100, null=False, blank=False)
description = models.TextField(default="")
category = models.ForeignKey(NewCategory, on_delete=models.CASCADE, null=True,
blank=True)
def __str__(self):
return str(self.title)
class Rootitem(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True,
verbose_name="Created By")
title = models.CharField(max_length=100, null=False, blank=False)
description = models.TextField(default="")
sub_category = models.ForeignKey(NewSubcategory, on_delete=models.CASCADE,
null=True, blank=True)
def __str__(self):
return str(self.title)
Serializers.py
I add #property function name in MasterCategorySerializer fields, "category", "sub_category", "root_item"
from .models import MasterCategory, NewCategory, NewSubcategory, Rootitem
from rest_framework import serializers
class MasterCategorySerializer(serializers.ModelSerializer):
class Meta:
model = MasterCategory
fields = ["title", 'category', 'sub_category', 'root_item']
class NewCategorySerializer(serializers.ModelSerializer):
class Meta:
model = NewCategory
fields = "__all__"
class NewSubcategorySerializer(serializers.ModelSerializer):
new_cat = NewCategorySerializer(source='category',read_only=True, many=True)
class Meta:
model = NewSubcategory
fields = "__all__"
class RootitemSerializer(serializers.ModelSerializer):
class Meta:
model = Rootitem
fields = "__all__"
**Viewset.py**
from API_app.models import MasterCategory
from API_app.serializers import MasterCategorySerializer
from rest_framework import viewsets
class MasterCategoryViewSet(viewsets.ModelViewSet):
queryset = MasterCategory.objects.all()
serializer_class = MasterCategorySerializer
My Desired Output, what i want.
{
Electronics <---- Master-Category
{
Smart-Phone <---- Category
{
Samsung <---- Sub-Category
{
Samsung S20 Ultra <---- Root-Item
}
}
}
}
Change your serializers as below. For this nested structure you don't need properties. As tables are connected with foreign key you can define related name between models and assign to its serializer. Default related name between table is tablename_set.
class RootitemSerializer(serializers.ModelSerializer):
class Meta:
model = Rootitem
fields = "__all__"
class NewSubcategorySerializer(serializers.ModelSerializer):
rootitem_set = RootitemSerializer(many=True)
class Meta:
model = NewSubcategory
fields = "__all__"
class NewCategorySerializer(serializers.ModelSerializer):
newsubcategory_set = NewSubcategorySerializer(many=True)
class Meta:
model = NewCategory
fields = "__all__"
class MasterCategorySerializer(serializers.ModelSerializer):
newcategory_set = NewCategorySerializer(many=True)
class Meta:
model = MasterCategory
fields = "__all__"
We have relationship between MasterCategory and NewCategory. As you don't define related_name therefore related name is newcategory_set and its response is NewCategorySeralizer. Make many=True because they are related with foreign key as there can be multiple newcategory related to mastercategory. Other relations are same as above explanation.
If you want to change this default related name then look at related_name, you can define it inside models.ForeignKey()

how to use django Serializer or signal to add object in database?

I create ticket , ticketflow , ticketstate , tickettype models
i need a serializer or signal that when user create ticket programmatically add ticketflow object and set state of ticket to submited or something else
Here is my models
class TicketType(models.Model):
title = models.CharField(max_length=255, blank=False, unique=True, null=False)
def __str__(self):
return self.title
class TicketState(models.Model):
title = models.CharField(max_length=255, blank=False, unique=True, null=False)
def __str__(self):
return self.title
class Ticket(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4 , editable=False)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE)
ticket_type = models.ForeignKey(TicketType,on_delete=models.CASCADE , default=1)
title = models.CharField(max_length=255, blank=False, null=False)
message = models.TextField()
attachment = models.FileField(upload_to='uploads/tickets/', validators=[FileExtensionValidator(allowed_extensions=['pdf','docx','zip','jpg','png'])], blank=True)
created_on = models.DateTimeField(auto_now_add=True)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
class TicketFlow(models.Model):
uuid = models.UUIDField(default=uuid4, editable=False)
author = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete= models.CASCADE)
ticket = models.ForeignKey(Ticket,on_delete=models.CASCADE , related_name='ticketflow')
ticket_state = models.ForeignKey(TicketState,on_delete=models.CASCADE , default=1 , related_name='ticketstate')
message = models.TextField()
attachment = models.FileField(upload_to='uploads/tickets/', validators=[FileExtensionValidator(allowed_extensions=['pdf','docx','zip','jpg','png'])], blank=True)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now= True)
class Meta:
ordering = ['-created_on']
here is my serializers
class TicketTypeSerializer(serializers.ModelSerializer):
class Meta:
model = TicketType
fields = ('id','title',)
class TicketStateSerializer(serializers.ModelSerializer):
class Meta:
model = TicketState
fields = ('id','title',)
class TicketSerializer(serializers.ModelSerializer):
class Meta:
model = Ticket
fields = ['id' , 'author', 'ticket_type','title' ,'message' , 'attachment' , 'created_on']
class TicketFlowSerializer(serializers.ModelSerializer):
class Meta:
model = TicketFlow
fields = ['author', 'ticket_state', 'message', 'attachment', 'created_on', 'updated_on']
It'll be great if someone can help me out in this. how can i create signal or override create method in serializers
You probably want your "state" field to be read-only in the serializer, this way it can only be changed programmatically, and in the model set a default value with default='pending'.
Then you can override the update method in a Serializer (see the doc here):
def update(self, instance, validated_data):
validated_data['state'] = 'edited'
return super(MySerializer, self).update(instance, validated_data)

Django Import Export, Filter ForeignKey objects connected to users

I'm building an import excel files system for every leads whit an import-export library. On the Website, each user must be able to import his leads and make sure that they are viewed only by him. In all other cases, I filtered the "organisation" field linked to a UserProfile model through the views.py. But now I don't know how to filter the field organisation for a specific user. At the moment I can import the excel files from the template but leave the organisation field blank. Help me please I'm desperate
Models.py
class Lead(models.Model):
nome = models.CharField(max_length=20)
cognome = models.CharField(max_length=20)
luogo=models.CharField(max_length=50, blank=True, null=True, choices=region_list)
città=models.CharField(max_length=20)
email = models.EmailField()
phone_number = models.CharField(max_length=20)
description = models.TextField()
agent = models.ForeignKey("Agent", null=True, blank=True, on_delete=models.SET_NULL)
category = models.ForeignKey("Category", related_name="leads", null=True, blank=True, on_delete=models.SET_NULL)
chance=models.ForeignKey("Chance",related_name="chance", null=True, blank=True, on_delete=models.CASCADE)
profile_picture = models.ImageField(null=True, blank=True, upload_to="profile_pictures/")
converted_date = models.DateTimeField(null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
organisation = models.ForeignKey(UserProfile, on_delete=models.CASCADE,null=True, blank=True)
objects = LeadManager()
age = models.IntegerField(default=0)
def __str__(self):
return f"{self.nome} {self.cognome}"
class User(AbstractUser):
is_organisor = models.BooleanField(default=True)
is_agent = models.BooleanField(default=False)
class UserProfile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
def __str__(self):
return self.user.username
Views.py
def simple_upload(request):
if request.method == 'POST':
Lead_resource = LeadResource()
dataset = Dataset()
newdoc = request.FILES['myfile']
imported_data = dataset.load(newdoc.read(),format='xlsx')
#print(imported_data)
for data in imported_data:
value = Lead(
data[0],
data[2],#nome
data[3],#cognome
data[5],#luogo
data[7],#città
data[8],#email
data[9],#numero telefono
data[11],#desc
)
value.save()
result = Lead_resource.import_data(dataset, dry_run=True) # Test the data import
if not result.has_errors():
Lead_resource.import_data(dataset,dry_run=False) # Actually import now
return render(request, 'input.html')
Resources.py
class LeadResource(resources.ModelResource):
nome = fields.Field(attribute='nome', column_name='nome')
luogo = fields.Field(attribute='luogo', column_name='regione')
class Meta:
model = Lead
report_skipped=True
admin.py
#admin.register(Lead)
class PersonAdmin(ImportExportModelAdmin):
readonly_fields = ('date_added',)

Django Model, Multi value / Admin Area

I have start fresh with Django.
I am creating a blog and I need a hint now.
I want to add tags to my posts.
So I created a model for my tags:
class Tag(models.Model):
name = models.CharField(max_length=200, unique=True)
def __str__(self):
return self.name
This is my Post Model
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
What is the best way, that the user can select in the admin area tags for the post and more than one or create a new tag?
In the Post class, add a field ManyToMany
class Post(models.Model):
title = models.CharField(max_length=200, unique=True)
slug = models.SlugField(max_length=200, unique=True)
author = models.ForeignKey(User, on_delete= models.CASCADE,related_name='blog_posts')
updated_on = models.DateTimeField(auto_now= True)
content = models.TextField()
created_on = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(choices=STATUS, default=0)
tag = models.ManyToManyField(Tag)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
You are looking for InlineModelAdmin particulary section regarding
Working with many-to-many models
something as following:
class TagInline(admin.TabularInline):
model = Post.tags.through
class PostAdmin(admin.ModelAdmin):
inlines = [
TagInline,
]
Also you are missing relationship on your model which should be ManyToMany
class Post(models.Model):
...
tags = models.ManyToManyField(Tag)

django admin registration isn't showing up

I started a django tutorial "http://www.lightbird.net/dbe/photo.html", and have followed the instructions for 2 of their apps and neither is working. I am trying to register these models in admin and all I see on the admin page is "Authentication and Authorization, Groups, Users" stacked on top of each other. Where are my album, tags, and image admins? I ran syncdb before starting runserver
from django.db import models
from django.contrib import admin
from django.contrib.auth.model import User
class Album(models.Model):
title = models.CharField(max_length=60)
public = models.BooleanField(default=False)
def __unicode__(self):
return self.title
class Tag(models.Model):
tag = models.CharField(max_length=50)
def __unicode__(self):
return self.tag
class Image(models.Model)
title = models.CharField(max_length=60, blank=True, null=True)
image = models.FileField(upload_to="images/")
tags = models.ManyToManyField(Tag, blank=True)
albums = models.ManyToManyField(Album, blank=True)
created = models.DateTimeField(auto_now_add=True)
rating = models.IntegerField(default=50)
width = models.IntegerField(blank=True, null=True)
height = models.IntegerField(blank=True, null=True)
user = models.ForeignKey(User, blank=True, null=True)
def __unicode__(self):
return self.image.name
class AlbumAdmin(admin.ModelAdmin):
search_field = ["title"]
list_display = ["title"]
class TagAdmin(admin.ModelAdmin):
list_display = ["tag"]
class ImageAdmin(admin.ModelAdmin):
search_fields = ["title"]
list_display = ["__unicode__", "title", "user", "rating", "created"]
list_filter = ["tags", "albums"]
admin.site.register(Album, AlbumAdmin)
admin.site.register(Tag, TagAdmin)
admin.site.register(Image, ImageAdmin)