Let say I have two model.
I want to make subject field in Program model appear in UserProgramAdmin.
What is the best way to do that?
class Program(models.Model):
name = models.CharField(max_length=15, blank=False)
summary = models.CharField(max_length=200, blank=True)
subject = models.ManyToManyField(Subject, related_name='all_subjects')
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True, editable=False)
updated_at = models.DateTimeField(auto_now=True, editable=False)
def __str__(self) -> str:
return self.name
class UserProgram(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
)
program = models.ForeignKey(
Program,
on_delete=models.CASCADE,
)
is_active = models.BooleanField(default=True)
is_finish = models.BooleanField(default=False, editable=False)
/admin.py
class UserProgramAdmin(admin.ModelAdmin):
list_display = ('user', 'program' , 'is_active', 'is_finish')
Thanks in advance
You should define a method on UserProgram and then call it in your UserProgramAdmin list_display attribute
models.py
class UserProgram(models.Model):
#...model attributes
def get_subject(self):
subject = self.program.subject.all()
return subject
admin.py
class UserProjectAdmin(admin.ModelAdmin):
list_display = ('get_subject', 'attribute_to_display')
The best way to do this would be to also show subject in the __str__ in Program field like this:
class Program(models.Model):
#Your other code
def __str__(self):
return f'{self.name} - {self.subject}'
Then the subject of Program shows up in the admin of UserProgram.
Related
I have below models and form.
Brand > Section > Category > Article.
I can pull the existing data out of the database however I have hit a wall. I am trying to create a new article or update an existing article but I'm not sure how I can update the brand, then the Section. The Category I can update and it is connected directly to the Article model. I have been thinking about this for a few days now and tried different models but ultimately i can't think of the best way to connect the models and have them update in the model.
class Brand(models.Model):
def brand_image(instance, filename):
return 'uploads/brand/{0}/{1}'.format(instance.title, filename)
title = models.CharField(max_length=50, unique=True, blank=True, null=True)
image = models.ImageField(upload_to=brand_image, null=True, blank=True)
slug = AutoSlugField(populate_from='title', unique_with='title', blank=True, null=True)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('brand-list', kwargs={'brand_slug': self.slug})
class Section(models.Model):
title = models.CharField(max_length=50,unique=True, blank=True,null=True)
slug = AutoSlugField(populate_from='title', unique_with='title',blank=True,null=True)
brand = models.ForeignKey(Brand, on_delete=models.CASCADE, related_name='section', blank=False, null=False)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('section-list', kwargs={'section_slug': self.slug})
class Category(models.Model):
title = models.CharField(max_length=50, blank=True,null=True)
slug = AutoSlugField(populate_from='title', unique_with='title',blank=True,null=True)
my_order = models.PositiveIntegerField(default=0, blank=False, null=False)
section = models.ForeignKey(Section, on_delete=models.CASCADE,related_name='category', blank=False ,null=False)
class Meta:
ordering = ['my_order']
def __str__(self):
return self.title or ''
def get_absolute_url(self):
return reverse('category-list', kwargs={'category_slug': self.slug})
class Article(models.Model):
title = models.CharField(max_length=100, unique=True, db_index=True)
description = models.CharField(max_length=100, blank=True, null=False)
category = models.ForeignKey(Category, on_delete=PROTECT, related_name='article', null=False, default=1)
slug = AutoSlugField(populate_from='title', unique_with='created__month')
content = HTMLField(null=True,blank=True)
internal = models.BooleanField(default=False)
status = models.CharField(max_length=30, choices=STATUS_CHOICES, default='Draft')
author = models.ForeignKey(User, related_name='author' ,on_delete=PROTECT,null=True)
updated_by = models.ForeignKey(User, related_name='updated_by',on_delete=PROTECT,null=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
video = models.FileField(blank=True, null=True, upload_to='articles/videos')
favourites = models.ManyToManyField(User, related_name='art_favourite', default=None, blank=True)
tags = TaggableManager(related_name='tags', help_text='Comma or space separated list', blank=True)
pinned = models.BooleanField(default=False)
def __str__(self) -> str:
return self.title
def get_absolute_url(self):
return reverse('articles-detail', kwargs={'article_slug': self.slug})
class ArticleForm(forms.ModelForm):
title = forms.CharField(label='Article Title', max_length=100,)
description = forms.CharField(label='Description', max_length=100,required=False)
content = forms.CharField(label='Article Content',widget=CKEditorUploadingWidget(attrs={'cols': 80, 'rows': 30}))
video = forms.FileField(help_text="Valid file Extension - .mp4", required=False, validators=[validate_file_extension])
category = GroupedModelChoiceField(queryset=Category.objects.exclude(section=None).order_by('section'),choices_groupby='section')
internal = forms.BooleanField(required=False, help_text='Is this for internal use only?', label='Internal Article')
class Meta:
model = Article
exclude = ['slug','author','created','updated','updated_by','favourites','votes','views','section']
widgets = {"tags": TagWidget(attrs={"data-role": "tagsinput"})}
Any help or guidance would be greatly appreciated.
Your Article model has a foreign key link to Section for some reason. However your stated heirarchy and models use the following one-to-many relations, which creates a direct link up the chain.
Brand < Section < Category < Article.
This means that by choosing the Category you could also choose Brand and Section. If your Article had a foreign key link to Category instead, then all the information above about groups above Article could be obtained via the article, eg, article.category__section__brand. Changing the category would, by default, update section and brand. You could do this in a single dropdown that contained Category.objects.all - perhaps with the dropdown option text also containing brand and section info for clarity and sorting purposes.
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)
Hey i have problem with the categories parent. As you can see in the code i have category with a foreign key pointing to it self. Now i dont want a instance of category to be a child of itself. So far i have tried unique_together and UniqueConstraint but that didn't work.
class Category(models.Model):
parent = models.ForeignKey('self', related_name="children", on_delete=models.CASCADE, blank=True, null=True) #'self' to indicate a self-reference.
title = models.CharField(max_length=100)
slug = AutoSlugField(populate_from='title', unique=True, null=False, editable=True)
logo = models.ImageField(upload_to="catlogo", blank=True, null=True, help_text='Optional')
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Meta:
#enforcing that there can not be two categories under a parent with same slug
verbose_name_plural = "categories"
constraints = [
models.UniqueConstraint(fields=['slug', 'parent'], name='unique_parent')
]
You can add some validations for it yourself though, you should simply overwrite the validate_unique method and add this validation to it. Try this.
class Category(models.Model):
parent = models.ForeignKey('self', related_name="children", on_delete=models.CASCADE, blank=True, null=True) #'self' to indicate a self-reference.
title = models.CharField(max_length=100)
slug = AutoSlugField(populate_from='title', unique=True, null=False, editable=True)
logo = models.ImageField(upload_to="catlogo", blank=True, null=True, help_text='Optional')
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
class Meta:
verbose_name_plural = "categories"
def validate_unique(self, *args, **kwargs):
super(Category, self).validate_unique(*args, **kwargs)
if self.__class__.objects.\
filter(parent=self.parent, slug=self.slug).\
exists():
raise ValidationError(
message='Category with this (parent, slug) already exists.',
code='unique_together',
)
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)
I am a django newbie and have one more big struggle for longer time... :/
User can choose a 'main language' which is set as ForeignKey. User can choose 'further languages' as ManyToMany (Checkbox). Assuming, user selects english as 'main' language, so english has to be filterd out from the 'further languages'... have been searching so much and have no idea how to do it. Is this even possible without JavaScript?
Of course, I could set the 'queryset' in the second form but it would filter the objects after the submit... The similar problem is, when a selected country has to be connected to the proper zipcodes...
I am very thankful for any hints.
Best regards.
class Country(models.Model):
enter code here
country = models.CharField(max_length=40)
active = models.BooleanField(default=True)
class Meta:
verbose_name_plural = 'Länder'
def __str__(self):
return self.country
class ZipCode(models.Model):
zipcode = models.CharField(max_length=5)
city = models.CharField(max_length=255)
active = models.BooleanField(default=False)
class Meta:
verbose_name_plural = 'Postleitzahlen'
def __str__(self):
return '{0} {1}'.format(self.zipcode, self.city)
class MainLanguage(models.Model):
language = models.CharField(verbose_name='Hauptsprache', max_length=40)
active = models.BooleanField(default=True)
class Meta:
verbose_name_plural = 'Hauptsprachen'
ordering = ['language']
def __str__(self):
return self.language
class SecondLanguage(models.Model):
language = models.CharField(verbose_name='weitere Sprachen', max_length=40)
active = models.BooleanField(default=False)
class Meta:
verbose_name_plural = 'weitere Sprachen'
ordering = ['language']
def __str__(self):
return self.language
class CustomUserprofile(models.Model):
user = models.OneToOneField(User)
name = models.CharField(verbose_name='Vorname', max_length=40,
null=True, blank=True)
country = models.ForeignKey(Country, verbose_name='Land',
null=True, blank=True)
zipcode = models.ForeignKey(ZipCode, blank=True, null=True)
main_language = models.ForeignKey(
MainLanguage, verbose_name='Hauptsprache',
null=True, blank=True)
second_language = models.ManyToManyField(
SecondLanguage, verbose_name='weitere Sprachen',
null=True, blank=True)
class UserProfileForm(forms.ModelForm):
second_language = forms.ModelMultipleChoiceField(
queryset=SecondLanguage.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple)
class Meta:
model = CustomUserprofile
exclude = ('user',)