According to the django docs, a modelform field accepts attrs. When I attempt to apply attrs I get
TypeError: init() got an unexpected keyword argument 'attrs'
The form I'm attempting to make is pretty simple, I just want to apply style to it. What am I doing wrong?
forms.py
from django import forms
from .models import ServiceReportModel
class ServiceReportCreateForm(forms.ModelForm):
class Meta:
model = ServiceReportModel
fields = [
'request_number',
'request_reason',
'actions_taken',
]
class ServiceReportUpdateForm(forms.ModelForm):
class Meta:
model = ServiceReportModel
fields = [
'report_number',
'request_number',
'request_reason',
'actions_taken',
]
widgets = {
'report_number': forms.CharField(attrs={'class': 'form-control'}),
'request_number': forms.CharField(attrs={'class': 'form-control'}),
'request_reason': forms.CharField(attrs={'class': 'form-control'}),
'actions_taken': forms.Textarea(attrs={'class': 'form-control'}),
}
views.py
from django.views.generic.edit import CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from .forms import ServiceReportCreateForm, ServiceReportUpdateForm
from .models import ServiceReportModel
class ReportCreateView(CreateView):
form_class = ServiceReportCreateForm
model = ServiceReportModel
class ReportCreateView(UpdateView):
form_class = ServiceReportUpdateForm
model = ServiceReportModel
class ReportDeleteView(DeleteView):
model = ServiceReportModel
success_url = reverse_lazy('reports-list')
models.py
import uuid
from django.urls import reverse
from django.db import models
from django.forms import ModelForm
from main import models as main_models
from customers import models as customers_models
class ServiceReportModel(models.Model):
report_number = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
request_number = models.ForeignKey(ServiceRequestModel,
on_delete=models.PROTECT,
null=True,
related_name='s_report_number'
)
reported_by = models.ForeignKey(main_models.MyUser, editable=False, related_name='reports')
reported_date = models.DateTimeField(auto_now_add=True)
updated_by = models.ForeignKey(main_models.MyUser, editable=True, blank=True, null=True, related_name='+')
updated_date = models.DateTimeField(auto_now=True)
request_reason = models.CharField(max_length=255, null=True)
actions_taken = models.TextField()
def get_absolute_url(self):
return reverse('service-report', kwargs={'pk': self.pk})
Fields do not accept attrs, widgets do. And similarly the widgets dictionary expects widgets not fields. You should use TextInput.
Related
Codes are given below.
users.model.py
from django.contrib.auth.models import AbstractBaseUser, PermissionsMixin
from django.db import models
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from django.db import models
# from django.contrib.auth.models import User
from PIL import Image
from .managers import CustomUserManager
from django.contrib import admin
from django.contrib.auth.models import AbstractUser
from django.utils.translation import ugettext_lazy as _
class CustomUser(AbstractUser):
username = None
first_name = models.CharField('Name',max_length=200,unique=True)
email = models.EmailField(_('email address'), unique=True)
registration = models.IntegerField()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = []
objects = CustomUserManager()
def __str__(self):
return self.email
class Profile(models.Model):
user = models.OneToOneField(CustomUser, on_delete=models.CASCADE)
image = models.ImageField(default='default.jpg', upload_to='profile_pics')
blog.model.py
from django.db import models
from django.utils import timezone
from django.urls import reverse
from django.conf import settings
from multiselectfield import MultiSelectField
from django import forms
from django.core.validators import MinValueValidator, MaxValueValidator
from PIL import Image
DAYS_OF_WEEK = [
(0, ' Monday'),
(1, ' Tuesday'),
(2, ' Wednesday'),
(3, ' Thursday'),
(4, ' Friday'),
(5, ' Saturday'),
(6, ' Sunday'),
]
class PostManager(models.Manager):
def like_toggle(self, user, post_obj):
if user in post_obj.liked.all():
is_liked = False
post_obj.liked.remove(user)
else:
is_liked = True
post_obj.liked.add(user)
return is_liked
class Post(models.Model):
author = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
title = models.CharField('Doctor\'s Name',max_length=100)
content = models.CharField('Specialty',max_length=100)
chamber = models.CharField('Chamber\'s Name',max_length=200)
address = models.CharField('Address',max_length=100, blank=True)
fees = models.IntegerField(default=0)
days = MultiSelectField('Available Days', choices= DAYS_OF_WEEK)
start_time = models.TimeField('Chamber Beginning Time')
end_time = models.TimeField('Chamber Ending Time')
image = models.ImageField( upload_to='profile_pics')
review = models.TextField()
rating = models.IntegerField('Behavior')
overall_rating = models.PositiveIntegerField(validators=[
MaxValueValidator(10),
MinValueValidator(0)
])
liked = models.ManyToManyField(
settings.AUTH_USER_MODEL, blank=True, related_name='liked')
date_posted = models.DateTimeField(default=timezone.now)
objects = PostManager()
class Meta:
ordering = ('-date_posted', )
def get_absolute_url(self):
return reverse('post_detail', kwargs={'pk': self.pk})
def save(self):
super().save() # saving image first
img = Image.open(self.image.path) # Open image using self
if (img.height > 1020 or img.width > 1920):
new_img = (1020, 1920)
img.thumbnail(new_img)
img.save(self.image.path) # saving image at the same path
class Comment(models.Model):
post = models.ForeignKey(
Post, related_name='comments', on_delete=models.CASCADE)
author = models.ForeignKey(
settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
approved_comment = models.BooleanField(default=True)
def approve(self):
self.approved_comment = True
self.save()
def get_absolute_url(self):
return reverse("post_list")
def __str__(self):
return self.author
I have created a project. In that project there are two apps named: user and blog. I'm saving the CustomUsers in Profile.
I want to use the user.model.py file's first_name field value as blog.model.py file's title field.
I'm new to django.Help me fix this issue!
In Blog app do
from user.models import model1,model2
In user App you can import Blog models like
from blog.models import model1,model2
I am begginer in django. I would like to add some posts and comments but I am getting an Integrity error.
Without comments model it was working before but it doesn´t work together. I already delete my database and makemigrations and migrate again.
post models
from django.db import models
from django.conf import settings
# from django.contrib.auth import get_user_model
# User = get_user_model()
# Create your models here.
class Post(models.Model):
user = models.ForeignKey(
#to=User,
to=settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name='posts',
null=True
)
content = models.CharField(
max_length=150,
blank=False
)
created = models.DateTimeField(
auto_now=True
)
liked_by = models.ManyToManyField(
#to=User,
to=settings.AUTH_USER_MODEL,
related_name='liked_posts',
blank=True
)
post serializer
from rest_framework import serializers
from .models import Post
from ..comment.serializers import CommentSerializer
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
comments = CommentSerializer(source='comments.content')
fields = [
'id',
'user',
'content',
'comments',
'created',
'liked_by',
]
comment.models
from django.db import models
from django.conf import settings
from apps.post.models import Post
# Create your models here.
class Comment(models.Model):
user = models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='comment', null=True)
post = models.ForeignKey(to=Post, on_delete=models.SET_NULL, related_name='comment', null=True)
content = models.CharField(max_length=150)
created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f'Comment by: {self.user}'
comment serializer
from rest_framework import serializers
from .models import Comment
class CommentSerializer(serializers.ModelSerializer):
class Meta:
model = Comment
fields = ['id', 'user', 'post', 'content', 'created']
you need to pass the CommentSerializer field in PostSerializer Meta class properly.
from rest_framework import serializers
from .models import Post
from .comment.serializers import CommentSerializer
class PostSerializer(serializers.ModelSerializer):
comments = CommentSerializer(many=True)
class Meta:
model = Post
fields = [
'id',
'user',
'content',
'comments',
'created',
'liked_by',
'comments',
]
I am new to Django and working on a project.
I have these models
class Test(models.Model):
name = models.CharField(max_length=255)
description = models.CharField(max_length=255, blank=True)
applicable_device = models.ManyToManyField(Device)
applicable_platform = models.ManyToManyField(Platform)
class Meta:
verbose_name = 'Test'
verbose_name_plural = 'Tests'
def __str__(self):
return self.name
class Event(models.Model):
name = models.CharField(max_length=255)
test = models.ManyToManyField(Test)
applicable_devices = models.ManyToManyField(Device)
class Meta:
verbose_name = 'Event'
verbose_name_plural = 'Events'
def __str__(self):
return self.name
class Property(models.Model):
name = models.CharField(max_length=255)
description = models.CharField(max_length=255)
applicable_events = models.ManyToManyField(Event)
applicable_devices = models.ManyToManyField(Device)
applicable_platform = models.ManyToManyField(Platform)
property_type = models.CharField(max_length=20, choices=TYPE_CHOICES)
expected_value = ArrayField(models.CharField(max_length=200), blank=True)
When I go to the Event section in the Django Admin Panel I am able to edit the events. But I want to be able to see a list of all the properties that apply to it underneath where I edit the event.
Is this possible?
I am not sure of what you have allready done in your admin .py. Did you modify your admin.py file and your form.py ?
form.py
from . import models
from django.forms.models import ModelForm
class EventForm(ModelForm):
class Meta:
model = models.Event
fields = ('id','name','test', 'applicable devices')
admin.py
from . import models
from . import forms
from django.contrib import admin
class EventAdmin(admin.ModelAdmin):
form = forms.EventForm
list_display = ['name','test', 'applicable devices']
# then to register your ModelAdmin
admin.site.register(Event, EventAdmin)
````
I am trying to be able to serialize and upload multiple images to associate with each post.
This is my models.py
from django.conf import settings
from django.db import models
from django.db.models.signals import pre_save
from .utils import unique_slug_generator
class Painting(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, default="", on_delete=models.CASCADE)
title = models.CharField(blank=False, null=False, default="", max_length=255)
slug = models.SlugField(blank=True, null=True)
style = models.CharField(blank=True, null=True, default="", max_length=255) #need to figure out why there is problem when this is False
description = models.TextField(blank=True, null=True, default="")
size = models.CharField(blank=True, null=True, default="", max_length=255)
artist = models.CharField(blank=True, null=True, default="", max_length=255)
price = models.DecimalField(blank=True, null=True, decimal_places=2, max_digits=20)
available = models.BooleanField(default=True)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
def __str__(self):
return self.title
class Meta:
ordering = ["-timestamp", "-updated"]
class PaintingPhotos(models.Model):
title = models.ForeignKey(Painting, default="", on_delete=models.CASCADE)
image = models.ImageField(upload_to='uploaded_paintings')
def pre_save_painting_receiver(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = unique_slug_generator(instance)
pre_save.connect(pre_save_painting_receiver, sender=Painting)
my serializers.py
from django.contrib.auth import get_user_model, authenticate, login, logout
from django.db.models import Q
from django.urls import reverse
from django.utils import timezone
from rest_framework import serializers
from .models import Painting, PaintingPhotos
User = get_user_model()
class UserPublicSerializer(serializers.ModelSerializer):
username = serializers.CharField(required=False, allow_blank=True, read_only=True)
class Meta:
model = User
fields = [
'username',
'first_name',
'last_name',
]
# # add PaintingImagesSerializer with the images model here
class PaintingPhotosSerializer(serializers.ModelSerializer):
class Meta:
model = PaintingPhotos
fields =[
'image'
]
#becareful here, if anyone submits a POST with an empty title, it will result in the empty slug, (which will mess up the url lookup since the title is the slug in this case)
#make title a required field in the actual interface, also remember to don't submit s POST with an empty title from the Django restframework directly
class PaintingSerializer(serializers.ModelSerializer):
url = serializers.HyperlinkedIdentityField(
view_name='paintings-api:detail',
read_only=True,
lookup_field='slug'
)
user = UserPublicSerializer(read_only=True)
owner = serializers.SerializerMethodField(read_only=True)
image = PaintingPhotosSerializer(many=True, read_only=False)
class Meta:
model = Painting
fields = [
'url',
'user',
'title',
'style',
'description',
'size',
'artist',
'price',
'available',
'updated',
'timestamp',
'owner',
'slug',
'image',
]
def get_owner(self, obj):
request = self.context['request']
if request.user.is_authenticated:
if obj.user == request.user:
return True
return False
my views.py
from rest_framework.views import APIView
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.response import Response
from rest_framework import generics, permissions, pagination, status
from .models import Painting
from .permissions import IsOwnerOrReadOnly
from .serializers import PaintingSerializer
class PaintingPageNumberPagination(pagination.PageNumberPagination):
page_size = 5
page_size_query_param = 'size'
max_page_size = 20
def get_paginated_response(self, data):
author = False
user = self.request.user
if user.is_authenticated:
author = True
context = {
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'count': self.page.paginator.count,
'author': author,
'results': data,
}
return Response(context)
class PaintingDetailAPIView(generics.RetrieveUpdateDestroyAPIView):
queryset = Painting.objects.all()
serializer_class = PaintingSerializer
lookup_field = 'slug'
permission_classes = [IsOwnerOrReadOnly]
class PaintingListCreateAPIView(generics.ListCreateAPIView):
queryset = Painting.objects.all()
serializer_class = PaintingSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
pagination_class = PaintingPageNumberPagination
def perform_create(self, serializer):
serializer.save(user=self.request.user)
I am getting this error:
AttributeError: Got AttributeError when attempting to get a value for field image on serializer PaintingSerializer.
The serializer field might be named incorrectly and not match any attribute or key on the Painting instance.
Original exception text was: 'Painting' object has no attribute 'image'.
I am also not sure if I should create another app just to handle all the images.
Thanks so much in advance!
Your code looks similar enough to the docs here: https://www.django-rest-framework.org/api-guide/relations/#nested-relationships I can't see what exactly is wrong, but it could be that you haven't created a PaintingPhotos object so there is no model to serialize it. I mentioned in a comment that you can create this through the Django admin.
Hey guys I ended up finding the answer. This stackoverflow answer explains it really well: Multiple images per Model
where I messed up was not adding the related_name argument to my photo in my PaintingPhotos model.
So I have a model fie, a forms.py file and a views.py file. The views file returns a detail view of a post, now I wish to add a model form of a comments model into the detail view so I can access it in d template as {{ form }}. I can do this with function-based views but finding it difficult to do with class-based views. Here are the code.
#models.py
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
title = models.CharField(max_length=50)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
date_posted = models.DateTimeField(default=timezone.now)
likes = models.ManyToManyField(User, blank=True, related_name='post_likes')
image = models.ImageField(null=False, blank=False, upload_to='post_images')
slug = models.SlugField(unique=True)
class Comment(models.Model):
post = models.ForeignKey(Post, on_delete=models.CASCADE)
text = models.CharField(max_length=150)
date_commented = models.DateTimeField(auto_now_add=True)
comment_by = models.ForeignKey(User, on_delete=models.CASCADE)
#forms.py
from django import forms
from users.models import Profile
from Post.models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['text', ]
#views.py
from django.views.generic import ListView, DetailView
class PostDetail(DetailView):
model = Post
template_name = 'Post/blog-detail.html'
Hope my question makes sense Thanks.
You can do it, for example:
class PostDetail(DetailView):
model = Post
template_name = 'Post/blog-detail.html'
def get_context_data(self, **kwargs):
context = super(PostDetail, self).get_context_data(**kwargs)
context['comment_form'] = CommentForm()
return context