Editing in Django admin reversed depended by foreign key - django

How in class QuestionsAdmin(admin.ModelAdmin) implement that in Django admin in Question can see all, add, edit and delete all Answers?
class Answer(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4)
value = models.TextField()
correct = models.BooleanField()
question = models.ForeignKey("Questions", models.DO_NOTHING)
class Question(models.Model):
id = models.UUIDField(primary_key=True, default=uuid4)
content = models.TextField()

Use Inline in ModelAdmin
In admin.py
from django.contrib.admin import StackedInline
class AnswerInline(StackedInline):
model = Answer
extra = 0
verbose_name = "Answer"
verbose_name_plural = "Answers"
class QuestionAdmin(admin.ModelAdmin):
inlines = [AnswerInline]
admin.site.register(Question, QuestionAdmin)
You can also use TabularInline instead of StackedInline depending on the style.

Related

Django Check for duplicates with 2 model fields

I have a model that looks like this:
class UssdCode(models.Model):
title = models.CharField(max_length=100)
code = models.CharField(max_length=100)
product = models.CharField(max_length=100)
How can I get the admin to alert me and reject my entry when I try to add a new object that has the same 'code' and 'product' as an object already in the database.
You make it unique together. Since django-2.2, you can use the UniqueConstraint [Django-doc] of the Django Constraint framework [Django-doc] for that:
# since Django-2.2
class UssdCode(models.Model):
title = models.CharField(max_length=100)
code = models.CharField(max_length=100)
product = models.CharField(max_length=100)
class Meta:
constraints = [
models.UniqueConstraint(fields=['code', 'product'], name='code_product')
]
Prior to django-2.2, you can use the unique_together meta option [Django-doc]:
# before Django-2.2 (still works on Django-3.0)
class UssdCode(models.Model):
title = models.CharField(max_length=100)
code = models.CharField(max_length=100)
product = models.CharField(max_length=100)
class Meta:
unique_together = [['code', 'product']]

fields in class Meta got invalid

models.py
class Product(models.Model):
title = models.CharField(max_length=200)
description = models.TextField()
price = models.DecimalField(decimal_places=5,max_digits= 1500)
summary = models.TextField()
featured = models.BooleanField()
def __str__(self):
return self.title
# return f'product title:{self.title}-product price:{self.price}'workok
class Meta:
ordering = ('-price',)
class Opinion(models.Model):
name = models.CharField(max_length=20)
email = models.EmailField(max_length=20)
body = models.TextField()
opinion_date = models.DateTimeField(auto_now_add=True)
active = models.BooleanField(default=False)
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='opinion_set')
def __str__(self):
return f'({self.name}) add opinion about ({self.product})'
forms.py:
from django.forms import ModelForm
from .models import Product #space after from keyword
class OpinionModelForm(ModelForm):
class Meta:
model = Product
fields = ['name','email','body','product']
invalid in code line :
fields = ['name','email','body','product'] #---- NOT WORK !!!
, but if i change above code to :
fields = "__all__" # ----it is WORKing ok without any problem !!
question : what is the error? I am not need all the fields in the Product model (like active boolean field), I need only 'name','email','body','product' fields .
According to the error and the code you provided the main problem is that you made a mistake in chosing model in serializer:
class OpinionModelForm(ModelForm):
class Meta:
model = Product
fields = ['name','email','body','product']
Serializer name is OpinionModelForm and listed fields belong to Opinion so I guess you actually wanted to serialize Opinion and no Product as you defined at this line:
model = Product
Simply change it to:
model = Opinion

Add Queryset to django updateview

I have an updateview in which a manager can go and edit all the fields for the associate. Looks like this:(requirement is to add associate_mgr in the as a dropdown in the updateview)enter image description here
views.py
class ReallocationTeam(LoginRequiredMixin,UpdateView):
model = UserDetails
form_class = ViewEditSample
def get_success_url(self):
return reverse('UserProfile:index')
forms.py
class ViewEditSample(ModelForm):
class Meta:
model = UserDetails
fields = ['associate_name','client','lob','associate_mgr']
The manager should be able to edit the "assciate_mgr" of that associate too.
models.py
associate_name = models.CharField(max_length=200)
associate_nbr = models.CharField(max_length=8, primary_key=True)
associate_email = models.EmailField()
associate_department_id = models.CharField(max_length=50)
associate_mgr = models.CharField(max_length=100,blank=True, null=True)
associate_exec = models.CharField(max_length=100,blank=True, null=True)
associate_org = models.CharField(max_length=100,blank=True,null=True)
title = models.CharField(null=True, blank=True, max_length=100)
date_of_service = models.CharField(null=True,blank=True,max_length=11)
is_manager = models.BooleanField(default=False)
is_exec = models.BooleanField(default=False)
is_team_lead = models.BooleanField(default=False)
but associate_mgr is not a choice field in my db.
I need to add a dropdown that contains associate_mgr in my UpdateView. How do I go about implementing that?
Should I go about writing a query to get all managers and populate them i a dropdow: like this mgr = UserDetails.objects.filter(is_manager=True) But then how do i store the selected in associate_mgr field in db?
You can override your form field in your ModelForm to be a ChoiceField with a list of choices: UserDetails.objects.filter(is_manager=True).values_list('name').
associate_mgr = forms.ChoiceField(choices=
UserDetails.objects.filter(is_manager=True).values_list('associate_name', 'associate_name')
)
Then the choice will automatically be saved (the 'associate_name' field value).
But it would probably be a better idea to use a ForeignKey on your model, rather than a CharField. That would enforce the values to be other UserDetails rather than just a string.

Django : Displaying ManyToManyField in admin page as a Table

I have the following two models.
class Question(models.Model):
id = models.AutoField(primary_key=True)
question_body = models.TextField(blank=True)
question_response = models.TextField(blank=True)
def __str__(self):
return self.question_body
class SIGRound(models.Model):
sig = models.CharField(max_length=9, choices=SIG_CHOICES)
round_number = models.IntegerField(default=1)
round_description = models.CharField(max_length=500)
questions = models.ManyToManyField(Question)
I want to use the SIGRound from the admin page and since it is a many to many field, many answers on StackOverflow suggested to use filter_horizontal or inline
So I implemented both and checked out how they looked, filter_horizontal does not give me what I want and with inline it looks like this:
This is the code I am currently using:
class QuestionInline(admin.TabularInline):
model = SIGRound.questions.through
#admin.register(SIGRound)
class SIGRoundAdmin(admin.ModelAdmin):
inlines=[QuestionInline]
But I want to display this field as a table, similar to list_display in the normal admin page, how would I go about doing this?

Django Rest Framework: field name 'likes' is not valid for model 'userPost' improperlyConfigured

In my Django Rest Framework api I am attempting to add a property to my model UserPosts that returns all likes for said post. Despite my best efforts I keep running into this error. Here is my post model below:
class UserPosts(models.Model):
userProfile = models.ForeignKey(UserProfile, related_name="posts", on_delete=models.CASCADE)
image = models.ImageField()
caption = models.CharField(max_length=240)
#property
def get_likes(self):
from liked.models import Like
return Like(post=self)
and here is my like model:
class Like(models.Model):
user = models.OneToOneField(UserProfile, on_delete=models.CASCADE,)
post = models.ForeignKey(UserPosts, on_delete=models.CASCADE)
liked_at = models.DateTimeField()
and lastly the post serializer:
class postSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.UserPosts
fields = ('userProfile', 'image', 'caption', 'likes')
Thanks.
You have at least three ways. First as #WillemVanOnsem said, by the many_to_one change the likes to like_set
class postSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = models.UserPosts
fields = ('userProfile', 'image', 'caption', 'like_set')
# ^^^^^
Second rename your model's property to likes and fix the queryset inside it
class UserPosts(models.Model):
userProfile = models.ForeignKey(UserProfile, related_name="posts", on_delete=models.CASCADE)
image = models.ImageField()
caption = models.CharField(max_length=240)
#property
def likes(self):
# ^^^^^
from liked.models import Like
return Like.objects.filter(post=self).values() or []
# solution you try ^^^^^^^
return self.like_set.values() or []
# more django way
And Third, the most simple and elegant way for me, is to remove your get_likes and add the related_name to the post ForeignKey:
class Like(models.Model):
user = models.OneToOneField(UserProfile, on_delete=models.CASCADE,)
post = models.ForeignKey(UserPosts, related_name='likes', on_delete=models.CASCADE)
# ^^^^^^^^^^^
liked_at = models.DateTimeField()