I have the field as part of a Room class
roomextra = models.ManyToManyField(
to='hotel.RoomExtra',
related_name='room_extra',
verbose_name='room extra',
)
whereby Django has created the many to many relationship for me. This relationship is displayed as a TabularInline:
admin.py
class RoomExtraInLine(admin.TabularInline):
model = Room.roomextra.through
extra = 1
verbose_name = _('Customise Room Extra')
verbose_name_plural = _('Customise Room Extra(s)')
form = AddRoomAddRoomExtrasForm
In the Django admin, if I add a room extra I get the text in the image below:
Room_roomextra object (5)
above the option I have selected. How can I change the Room_roomextra string?
Update
Code as requested
class RoomExtra(models.Model):
PER_PERSON = 0
PER_ROOM = 1
PER_CHOICES = [
(PER_PERSON, _('Person')),
(PER_ROOM, _('Room')),
]
name = models.CharField(max_length=100)
cost = models.DecimalField(
default="0.00",
max_digits=10,
decimal_places=2,
validators=[MinValueValidator(Decimal('0.00'))],
)
cost_per = models.IntegerField(
choices=PER_CHOICES,
default=PER_ROOM,
verbose_name=_('Cost per'),
)
def __str__(self):
return self.name
class Room(models.Model):
name = models.CharField(max_length=100)
type = models.ForeignKey(
to='hotel.RoomType',
on_delete=models.CASCADE,
)
location = models.ForeignKey(
to='hotel.Location',
on_delete=models.CASCADE,
)
description = models.TextField(
blank=True,
max_length=500,
)
roomextra = models.ManyToManyField(
to='hotel.RoomExtra',
related_name='room_extra',
verbose_name='room extra',
)
bathroom = models.ForeignKey(
to='hotel.Bathroom',
on_delete=models.CASCADE,
)
available = models.BooleanField(default=True,)
def __str__(self):
return self.name
Adding a proxy model for Room // Room Extra allows the change of output text on the Django admin
class RoomRoomExtraProxy(Room.roomextra.through):
class Meta:
proxy = True
def __str__(self):
return self.room.name + ' // ' + self.roomextra.name
Related
I need to select 'changes' which related to sku id
I need help with views.py
models.py
Change
class Change (models.Model):
raw_current = models.ForeignKey(Raw, blank=True, null=True, on_delete=models.CASCADE, related_name='raw_current')
raw_new = models.ForeignKey(Raw, blank=True, null=True, on_delete=models.CASCADE, related_name='raw_new')
created_date = models.DateTimeField(default=timezone.now) # когда была создана заявка
def __str__(self):
return self.raw_current.num
def publish(self):
self.created_date = timezone.now()
self.save()
Raw
class Raw (models.Model):
num = models.CharField(max_length=200) # артикул сырья
name = models.CharField(max_length=200) # наименование
layer = models.CharField(max_length=200) # название слоя на русском
def __str__(self):
return self.num +' ' + self.name
Sku
class Sku (models.Model):
num = models.CharField(max_length=200) # артикул готоваой продукции (ГП)
name = models.CharField(max_length=200) # наименование ГП
raw = models.ManyToManyField(Raw, blank=True, null=True) # сырье
weight = models.IntegerField(blank=True, null=True) # вес
photo = models.ImageField(blank=True, null=True,
upload_to="images/") # фото
type = models.ForeignKey(ProductsTypes, blank=True, null=True, on_delete=models.CASCADE)
def __str__(self):
return self.num + ' ' + self.name
views.py
def change(request,sku_id):
sku = Sku.objects.get(id=sku_id)
list_change = Change.objects.filter(raw_current = sku.raw)
return render(request, 'main/change.html', {'sku':sku,'list_change':list_change,'change':change,})
urls.py
path('change/<sku_id>', views.change, name='change'),
TypeError at /change/1
Field 'id' expected a number but got <django.db.models.fields.related_descriptors.create_forward_many_to_many_manager.<locals>.ManyRelatedManager object at 0x10920d9f0>.
if in
views.py
def change(request,sku_id):
sku = Sku.objects.get(id=sku_id)
list_change = Change.objects.all()
return render(request, 'main/change.html',{'sku':sku,'list_change':list_change,'change':change,})
then i have the whole list but i need only changes belongs to selected sku
thanks for help
Because your raw field in Sku model is a ManyToManyField, you CANNOT do things like this:
list_change = Change.objects.filter(raw_current = sku.raw)
A ManyToManyField means that you can store not only one Raw in the Sku.raw field, and you can use sku.raw.all() to see all the Raws related to a specific sku object.
You can see the official document here.
Thus, if you want to filter all the Changes whose raw_current are equal to a bunch of Raws belongs to a sku, you can try something like this:
list_change = Change.objects.filter(raw_current__in=sku.raw.all())
I want to calculate most popular post by each category, but i have this error DISTINCT ON fields is not supported by this database backend.
after i use PostgreSql, but I also had a error. annotation and distinct together did not work.
model -->
class Category(models.Model):
title = models.CharField(max_length=150, verbose_name=_("კატეგორია"))
def __str__(self):
return self.title
class Question(models.Model):
user = models.ForeignKey(
User, on_delete=models.CASCADE, verbose_name=_("მომხმარებელი")
)
category = models.ManyToManyField(Category)
title = models.CharField(max_length=150, verbose_name=_("სათაური"))
body = models.TextField(verbose_name=_("ტექსტი"))
image = models.ImageField(blank=True, null=True, verbose_name=_("ფოტო"))
link = models.URLField(
max_length=400,
blank=True,
null=True,
validators=[RequireHttpOrHttpsUrl()],
verbose_name=_("ლინკი"),
)
time = models.DateTimeField(auto_now=True)
send_notification = models.BooleanField(
default=True, verbose_name=_("გავაგზავნოთ შეტყობინება?")
)
def __str__(self):
return self.title
class LikeDislike(models.Model):
user = models.ForeignKey(
User, on_delete=models.CASCADE, verbose_name=_("მომხმარებელი")
)
question = models.ForeignKey(
Question, on_delete=models.CASCADE, verbose_name=_("კითხვა")
)
point = models.BooleanField()
time = models.DateTimeField()
def __str__(self):
return self.question.title
view ->
class CountLikeByCategory(generics.ListCreateAPIView):
serializer_class = CountLikeByCategorySerializer
def get_queryset(self):
query=Question.objects.values_list(
'category__title','title'
).annotate(
l=Count('likedislike',filter=Q(likedislike__point=1)),
d=Count('likedislike',filter=Q(likedislike__point=0)),
total=F('l')+F('d'),
).order_by('category', '-total').distinct('category')
return query
who can help me?
i wan correct query
try this:
def get_queryset(self):
query=Question.objects.values_list(
'category','category__title','title'
).annotate(
l=Count('likedislike',filter=Q(likedislike__point=1)),
d=Count('likedislike',filter=Q(likedislike__point=0)),
total=F('l')+F('d'),
).order_by('category', '-total').distinct('category')
return query
i have 3 models in django like this:
class SlackConfigurationMode(models.Model):
MODES = (
("NORMAL", "normal"),
("ALERT", "alert"),
("DANGER", "danger")
)
mode = models.CharField(choices=MODES, default=MODES[0][0], max_length=20)
time_send_slack_notification_minute = models.IntegerField(default=0)
time_send_slack_notification_hour = models.IntegerField(default=0)
description = models.TextField(blank=True)
class WebHookConfiguration(models.Model):
webhook_url = models.CharField(max_length=100)
slack_configuration_mode = models.ForeignKey(
SlackConfigurationMode,
on_delete=models.CASCADE,
related_name='webhook_configurations'
)
class MonitorSource(models.Model):
TYPES = (
("FACEBOOK", "facebook"),
("WEBSITE", "website"),
("YOUTUBE", "youtube")
)
target = models.CharField(max_length=100)
type = models.CharField(choices=TYPES, max_length=20)
created_at = models.DateTimeField(auto_now_add=True)
owner = models.ForeignKey("auth.User", on_delete=models.CASCADE)
name = models.CharField(max_length=100)
slack_configuration = models.ForeignKey(
SlackConfigurationMode, on_delete=models.DO_NOTHING,
default=SlackConfigurationMode.objects.filter(mode="NORMAL")[0].id,
related_name='monitor_sources'
)
i want to get data of webhook_configuration and monitorsource filter by slackconfiguration by mode
i use this query:
queryset = SlackConfigurationMode.objects.select_related('webhook_configurations', 'monitor_sources').filter(
mode='HIGH'
)
but have the error:
Invalid field name(s) given in select_related: 'monitor_sources', 'webhook_configurations'. Choices are: (none)
how can i fix it, and why my query won't work, tks
Here, webhook_configurations and monitor_sources are reverese relations and hence you must use prefetch_related(...)
queryset = SlackConfigurationMode.objects \
.prefetch_related('webhook_configurations', 'monitor_sources') \
.filter(mode='HIGH')
I am making a CV page,
I want to link my Skill, Language etc class(table) to Main Person table/class,
But for that, I need to submit skill table first because my person table contains the foreign key for skills.
But as per CV form name & personal info comes first.
Also, I can put the whole form on one page but I want to go to the next page for each sub information, so is it possible to pass the request data from one class-based view to another class-based view.
models.py
from django.db import models
from django.core.validators import MinLengthValidator
from django.conf import settings
import datetime
class Workexperience(models.Model):
work = models.CharField(null=True, blank=True,
max_length=256,
help_text='eg: Juniorengineer: at L&T ')
person = models.ForeignKey('Person', on_delete=models.CASCADE, blank=True, null=False, default=1 )
def __str__(self):
return self.work
class Education(models.Model):
school = models.CharField(max_length=200)
college = models.CharField(null=True, blank=True,max_length=200)
person = models.ForeignKey('Person', on_delete=models.CASCADE, blank=True, null=False, default=1 )
def __str__(self):
return self.school
class Skills(models.Model):
skill = models.CharField(
max_length=256,
help_text='Add skills sperated by commas eg: programming, Matlab')
person = models.ForeignKey('Person', on_delete=models.CASCADE, blank=True, null=False, default=1 )
def __str__(self):
return self.skill
class Languages(models.Model):
language = models.CharField(
max_length=256,
help_text='Add language sperated by commas eg: English, Gujarati')
person = models.ForeignKey('Person', on_delete=models.CASCADE, blank=True, null=False, default=1 )
def __str__(self):
return self.language
class Person(models.Model):
name = models.CharField(
max_length=100,
help_text='Enter a name (e.g. Harry Virani)',
validators=[MinLengthValidator(2, "It must be greater than 1 character")]
)
picture = models.BinaryField(null=True, blank=True, editable=True)
content_type = models.CharField(max_length=256, null=True, blank=True,
help_text='The MIMEType of the file')
profession = models.CharField(
max_length=100,
validators=[MinLengthValidator(2, "It must be greater than 1 character")]
)
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, default='')
address = models.CharField(max_length=256)
email = models.EmailField(max_length = 254)
phone = models.CharField(
max_length=15,
help_text='Enter a phone number like this (e.g. +91000000000)',
validators=[MinLengthValidator(10, "It must be greater than 10 character")] )
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
facebook = models.URLField(null=True, blank=True, max_length=200,
help_text='enter your facebook URL' )
instagram = models.URLField(null=True, blank=True, max_length=200,
help_text='enter your instagram link URL' )
linkedin = models.URLField(null=True, blank=True, max_length=200,
help_text='enter your Linked link URL' )
skill = models.ManyToManyField(Skills, related_name='skills', default=1)
language = models.ManyToManyField(Languages, related_name='languages', default=1)
edu = models.ManyToManyField(Education, default=1,related_name='edu' )
work = models.ManyToManyField(Workexperience,default=1, blank=True, related_name='works')
# Shows up in the admin list
def __str__(self):
return self.name
views.py
I want to save it in another class which is for creating skill & other models.
class PersonCreateView(LoginRequiredMixin, View):
template_name = 'MYP/form.html'
success_url = 'MYP:myp_create_info'
def get(self, request, pk=None):
personform = PersonForm()
ctx = { 'personform': personform}
return render(request, self.template_name, ctx)
def post(self, request, pk=None) :
# if 'personform' in request.POST:
personform = PersonForm(request.POST, request.FILES or None)
if not personform.is_valid():
ctx = {'personform': personform}
return render(request, self.template_name, ctx)
pform = personform.save(commit=False)
#adding onwer
pform.owner = self.request.user
pform.save()
return redirect(self.success_url, pform.id)
class InfoCreateView(LoginRequiredMixin, View):
template_name = 'MYP/form2.html'
success_url = reverse_lazy('MYP:all')
def get(self, request, pk):
person = get_object_or_404(Person,id=pk)
skill= SkillsForm()
skill_list = Skills.objects.filter(person=person)
ctx = { 'skill':skill, 'skill_list':skill_list }
return render(request, self.template_name, ctx)
def post(self, request, pk):
if 'skill' in request.POST:
skill = SkillsForm(request.POST or None)
if not skill.is_valid() :
ctx = { 'skill':skill}
return render(request, self.template_name, ctx)
person = get_object_or_404(Person,id=pk)
print(person)
skill = Skills(skill=request.POST['skill'], person=person)
skill.save()
print(skill.person)
return redirect('MYP:myp_create_info', pk=pk)
forms.py
class PersonForm(forms.ModelForm):
max_upload_limit = 2 * 1024 * 1024
max_upload_limit_text = naturalsize(max_upload_limit)
# Call this 'picture' so it gets copied from the form to the in-memory model
# It will not be the "bytes", it will be the "InMemoryUploadedFile"
# because we need to pull out things like content_type
picture = forms.FileField(required=False, label='File to Upload <= '+max_upload_limit_text)
upload_field_name = 'picture'
# Hint: this will need to be changed for use in the ads application :)
class Meta:
model = Person
fields = ['name', 'profession', 'picture', 'address', 'email', 'phone','facebook','linkedin','instagram'] # Picture is manual
# Validate the size of the picture
def clean(self) :
cleaned_data = super().clean()
pic = cleaned_data.get('picture')
if pic is None : return
if len(pic) > self.max_upload_limit:
self.add_error('picture', "File must be < "+self.max_upload_limit_text+" bytes")
# Convert uploaded File object to a picture
def save(self, commit=True) :
instance = super(PersonForm, self).save(commit=False)
# We only need to adjust picture if it is a freshly uploaded file
f = instance.picture # Make a copy
if isinstance(f, InMemoryUploadedFile): # Extract data from the form to the model
bytearr = f.read();
instance.content_type = f.content_type
instance.picture = bytearr # Overwrite with the actual image data
if commit:
instance.save()
return instance
class WorkexperienceForm(forms.ModelForm):
class Meta:
model = Workexperience
fields = ['work']
class EducationForm(forms.ModelForm):
class Meta:
model = Education
fields = ['school','college']
class SkillsForm(forms.ModelForm):
class Meta:
model = Skills
fields = ['skill']
class LanguagesForm(forms.ModelForm):
class Meta:
model = Languages
fields = ['language']
Ignore the rest of the code it is just for image handling....
This is what I want to do but I know it is the wrong format
I want to just add id for everything later.
In my opinion, your models are messed up. Here is how I would have write them :
class WorkExperience(models.Model):
work = models.CharField(
blank=True,
max_length=256,
help_text='eg: Juniorengineer: at L&T'
)
def __str__(self):
return self.work
class Education(models.Model):
school = models.CharField(max_length=200)
college = models.CharField(blank=True, max_length=200)
def __str__(self):
return self.school
class Skill(models.Model):
name = models.CharField(
max_length=256,
help_text='Add a skill name (eg: Programming)'
)
def __str__(self):
return self.name
class Language(models.Model):
name = models.CharField(
max_length=256,
help_text='Add a language name (eg: Gujarati)'
)
def __str__(self):
return self.name
class Person(models.Model):
name = models.CharField(
max_length=100,
help_text='Enter a name (e.g. Harry Virani)',
validators=[MinLengthValidator(2, "It must be greater than 1 character")]
)
# [...Other fields...]
skills = models.ManyToManyField(Skill, related_name='persons', blank=True)
languages = models.ManyToManyField(Language, related_name='persons', blank=True)
educations = models.ManyToManyField(Education, related_name='persons', blank=True)
work_experiences = models.ManyToManyField(WorkExperience, related_name='persons', blank=True)
def __str__(self):
return self.name
Then I need to see your forms.py to better understand how you handle it in your view.
here is my model, serializer and output but when i want to create a new page it ask me to add a whole new user as its just a foreign-key it need to be a number like 1 (user id) and same in the case of categories how can i solve it.... help me please
serializers.py
class TeamMembersSerializer(serializers.ModelSerializer):
class Meta:
model = TeamMembers
fields = [
'user',
'page',
]
depth = 1
class SocialAccountsSerializer(serializers.ModelSerializer):
social = SocialCatSerializer()
class Meta:
model = SocialAccounts
fields = [
'page',
'social',
'link'
]
depth = 1
class PageImageSerializer(serializers.ModelSerializer):
class Meta:
model = PageImages
fields = [
'page',
'image',
]
depth = 1
class PageSerializer(serializers.ModelSerializer):
owner = UserSerializer()
catagory = BusinessCatSerializers()
business_type = BusinessTypeSerializer()
TeamMembers = TeamMembersSerializer(read_only=True)
social_accounts = SocialAccountsSerializer(read_only=True)
images = PageImageSerializer(read_only=True)
class Meta:
model =Page
fields = [
'id',
'owner',
'catagory',
'name',
'username',
'images',
'start_date',
'business_type',
'contect_number',
'email_address',
'website',
'TeamMembers',
'social_accounts',
'about',
'impression',
'Awards',
'Product',
'privacy_policy',
'is_active',
]
Models.py
class Page(models.Model):
owner = models.ForeignKey(User, on_delete=models.CASCADE)
catagory = models.ForeignKey(BusinessCatagories, on_delete=models.CASCADE, null=True, blank=True, default=None)
name = models.CharField(max_length=254, unique=True ,default=None, blank=True)
username = models.CharField(max_length=254, unique=True, blank=True)
start_date = models.DateTimeField(auto_now_add=True)
business_type = models.ForeignKey(BusinessType, on_delete=models.CASCADE, null=True, blank=True, default=None)
contect_number = models.CharField(max_length=254, default=None, blank=True)
email_address = models.EmailField(default=None, blank=True)
website = models.URLField(default=None, blank=True)
about = models.TextField(default=None, blank=True)
impression = models.TextField(default=None, blank=True)
Awards = models.CharField(max_length=254, default=None, blank=True)
Product = models.CharField(max_length=254, default=None, blank=True)
privacy_policy = models.URLField(default=None, blank=True)
is_active = models.BooleanField(default=True)
def __str__(self):
return self.name
class TeamMembers(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, default=None, blank=True)
page = models.ForeignKey(Page, on_delete=models.CASCADE, default=None, blank=True)
def __str__(self):
return self.user.name
class SocialAccounts(models.Model):
page = models.ForeignKey(Page, on_delete=models.CASCADE, default=None, blank=True)
social = models.ForeignKey(SocialCats, on_delete=models.CASCADE, default=None, blank=True)
link = models.URLField(default=None, blank=True)
def __str__(self):
return self.link
class PageImages(models.Model):
page = models.ForeignKey(Page, on_delete=models.CASCADE, default=None, blank=True)
image = models.ImageField(default=None, blank=True, upload_to=settings.MEDIA_ROOT)
def __str__(self):
return self.page.name
output is this but i need images field TeamMember field in it but its not appearing plus it want me to add a new user instead of asking for Foreignkey "id"
What you want is to use Primary key related field. It helps you to represent the target of the relationship using its primary key.
It should look somewhat like this.
Note: Mind the typo for any name
class PageSerializer(serializers.ModelSerializer):
owner = serializers.PrimaryKeyRelatedField(queryset = User.objects.all())
catagory = serializers.PrimaryKeyRelatedField(queryset = BuisnessCat.objects.all())
business_type = BusinessTypeSerializer()
TeamMembers = TeamMembersSerializer(read_only=True)
social_accounts = SocialAccountsSerializer(read_only=True)
images = PageImageSerializer(read_only=True)
You can read more about PrimaryKeyRelatedField here.
Now whenever creating any Page, all you need to supply are primary key for owner and category.
You are looking for Writable Nested Serializer.
In short you have to override create() method of PageSerializer
class PageSerializer(serializers.ModelSerializer):
....
....
your code
def create(self, validated_data):
# pop data of every related fields like "owner", "cateagory" etc from validated_data
owner = validated_data.pop("owner")
owner = User.objects.create(**owner)
category = validated_data.pop("category")
# create or retrieve category instance ,as above
...
...
...
# finally
return Page.objects.create(**validated_data,owner=owner,category=category, and other related instances)