AttributeError: 'CharField' object has no attribute 'use_required_attribute' - django-models

I try to add a form-control class to an input field of a model-based form in Django, but I get this error message:
AttributeError: 'CharField' object has no attribute 'use_required_attribute'.
How do I fix this?
class in views.py:
class TweetCreate(LoginRequiredMixin, CreateView):
model = TweetSearch
fields = ['search_term', 'query_type', 'start_date', 'end_date', 'language', 'country']
def get_form(self):
form = super().get_form()
form.fields['search_term'].widget = forms.CharField(max_length=200, widget=forms.TextInput(attrs={'class': 'form-control'}))
form.fields['query_type'].widget = forms.CharField(max_length=200, widget=forms.TextInput(attrs={'class': 'form-control'}))
form.fields['start_date'].widget = DateTimePickerInput(attrs={'class': 'form-control'})
form.fields['end_date'].widget = DateTimePickerInput(attrs={'class': 'form-control'})
form.fields['language'].widget = forms.CharField(max_length=200, widget=forms.TextInput(attrs={'class': 'form-control'})),
form.fields['country'].widget = forms.CharField(max_length=200, widget=forms.TextInput(attrs={'class': 'form-control'})),
return form
class in models.py:
class TweetSearch(models.Model):
from datetime import datetime, timedelta
search_term = models.CharField(max_length=200, default='blue bird')
QUERY_CHOICES = (
('t', 'in tweet'),
('h', 'in hashtag'),
('u', 'username'),
)
id = models.UUIDField(primary_key=True, default=uuid.uuid4, blank=True)
query_type = models.CharField(max_length=1, choices=QUERY_CHOICES, blank=True, default='t')
start_default = datetime.now() - timedelta(days=30)
start_date = models.DateTimeField(default=start_default)
end_date = models.DateTimeField(default=datetime.now)
language = models.CharField(max_length=200, default='English')
country = models.CharField(max_length=200, default='USA')
searcher = models.ForeignKey(User, on_delete=models.SET_NULL, null=True, blank=True)
def get_absolute_url(self):
return reverse('tweet_detail', kwargs={'pk': self.pk})
def __str__(self):
return f"Tweets with the word {self.search_term} from {self.start_date} till {self.end_date} written in " \
f"{self.language} in {self.country}."
HTML:
<div class="container" id="searchcontainer" style="text-align: center">
<form action="" method="POST">
{% csrf_token %}
{{form.search_term}}
{{form.query_type}}
{{form.start_date}}
{{form.end_date}}
{{form.language}}
{{form.country}}
<input class="btn btn-primary" type="submit">
</form>
</div>

You are confusing form field with widgets. You should assign a widget like TextInput, not a form field like CharField, like:
class TweetCreateView(LoginRequiredMixin, CreateView):
model = TweetSearch
fields = ['search_term', 'query_type', 'start_date', 'end_date', 'language', 'country']
def get_form(self):
form = super().get_form()
form.fields['search_term'].widget=forms.TextInput(attrs={'class': 'form-control'})
form.fields['query_type'].widget=forms.TextInput(attrs={'class': 'form-control'})
form.fields['start_date'].widget=DateTimePickerInput(attrs={'class': 'form-control'})
form.fields['end_date'].widget=DateTimePickerInput(attrs={'class': 'form-control'})
form.fields['language'].widget=forms.TextInput(attrs={'class': 'form-control'})
form.fields['country'].widget=forms.TextInput(attrs={'class': 'form-control'})
return form
It however here might be better to just plug in a ModelForm, so:
class TweetForm(forms.ModelForm):
class Meta:
model = TweetSearch
fields = ['search_term', 'query_type', 'start_date', 'end_date', 'language', 'country']
widgets = {
'search_term': forms.TextInput(attrs={'class': 'form-control'}),
'query_type': forms.TextInput(attrs={'class': 'form-control'}),
'start_date': DateTimePickerInput(attrs={'class': 'form-control'}),
'end_date': DateTimePickerInput(attrs={'class': 'form-control'}),
'language': forms.TextInput(attrs={'class': 'form-control'}),
'country': forms.TextInput(attrs={'class': 'form-control'}),
}
and plug this into the TweetCreateView:
class TweetCreateView(LoginRequiredMixin, CreateView):
model = TweetSearch
form_class = TweetForm
if you however only want to change the class, you can simplify this with:
class FormControlForm(forms.Form):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for field in self.fields.values():
field.widget.attrs['class'] = 'form-control'
class TweetForm(FormControlForm, forms.ModelForm):
class Meta:
model = TweetSearch
fields = ['search_term', 'query_type', 'start_date', 'end_date', 'language', 'country']

Related

Django Post request for many to many field ValueError

I am working on a post request in which the user chooses from a list of tags and makes combinations of tags. The combination of tags should then be posted. Nothing should get changed in the Tag table.
These are the models:
models.py
class Tag(models.Model):
name = models.CharField(max_length=256)
language = models.CharField(max_length=256)
objects = models.Manager()
def __str__(self):
"""Return a human readable representation of the model instance."""
return self.name or ''
#property
def tags(self):
tags = self.tagging.values('tag')
return tags.values('tag_id', 'tag__name', 'tag__language')
class Combination(models.Model):
user = models.ForeignKey(CustomUser, on_delete=models.SET_NULL, null=True)
gameround = models.ForeignKey(Gameround, on_delete=models.CASCADE, null=True)
resource = models.ForeignKey(Resource, on_delete=models.CASCADE, null=True)
tag_id = models.ManyToManyField(Tag, null=True)
created = models.DateTimeField(editable=False)
score = models.PositiveIntegerField(default=0)
objects = models.Manager()
def __str__(self):
return str(self.tag_id) or ''
This is the serializer for Combination.
serializers.py
class CombinationSerializer(serializers.ModelSerializer):
tag_id = TagWithIdSerializer(many=True, required=False, write_only=False)
resource_id = serializers.PrimaryKeyRelatedField(queryset=Resource.objects.all(),
required=True,
source='resource',
write_only=False)
gameround_id = serializers.PrimaryKeyRelatedField(queryset=Gameround.objects.all(),
required=False,
source='gameround',
write_only=False)
user_id = serializers.PrimaryKeyRelatedField(queryset=CustomUser.objects.all(),
required=False,
source='user',
write_only=False)
class Meta:
model = Combination
depth = 1
fields = ('id', 'user_id', 'gameround_id', 'resource_id', 'tag_id', 'created', 'score')
def create(self, validated_data):
user = None
request = self.context.get("request")
if request and hasattr(request, "user"):
user = request.user
score = 0
tag_data = validated_data.pop('tag_id', None)
combination = Combination(
user=user,
gameround=validated_data.get("gameround"),
resource=validated_data.get("resource"),
created=datetime.now(),
score=score
)
combination.save()
for tag_object in tag_data[0]:
combination.tag_id.add(tag_object)
return combination
def to_representation(self, instance):
rep = super().to_representation(instance)
rep['tag_id'] = TagWithIdSerializer(instance.tag_id.all(), many=True).data
return rep
I have tried posting the following JSON object to the database:
{
"gameround_id": 2015685170,
"resource_id": 327888,
"tag_id": [{"id": 2014077506, "name": "corwn","language": "en"}]
}
I am getting a ValueError: Field 'id' expected a number but got 'name'.
How can I fix this issue?
you need to provide tag id for each tag not all tag data,
Try like this
{
"gameround_id": 2015685170,
"resource_id": 327888,
"tag_id": [2014077506,2014077507]
}

__str__ returned non-string (type Category). when I add post from admin

After I added user and date_added in the Photo models, when I add post from admin its throws me an error saying: str returned non-string (type Category), when I click on the addpost link in the home template its throw another error: 'tuple' object has no attribute 'name'. how can I solve that ?
the models.py:
from django.db import models
from cloudinary.models import CloudinaryField
from django.contrib.auth.models import User
# Create your models here.
class Category(models.Model):
name = models.CharField(max_length=100, null=False, blank=False)
def __str__(self):
return self.name
class Photo(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True,
blank=True)
image = CloudinaryField('image')
description = models.TextField(null=True)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.category
the view.py file:
def home(request):
category = request.GET.get('category')
if category == None:
photos = Photo.objects.all()
else:
photos = Photo.objects.filter(category__name=category)
categories = Category.objects.all()
context = {'categories': categories, 'photos': photos}
return render(request, 'home.html', {'categories': categories, 'photos': photos} )
def viewPhoto(request, pk):
photo = Photo.objects.get(id=pk)
return render(request, 'photo.html', {'phpto': photo})
class PostCreativeView(LoginRequiredMixin, CreateView):
model = Photo, Category
fields = ['description', 'image', 'category', 'name']
template_name = 'post_create.html'
def form_valid(self, form):
form.instance.user = self.request.user
return super (PostCreativeView, self).form_valid(form)
Well it has to do with your category name and model you added into post create view.py and so you
have do something like this:
views.py
class PostCreativeView(LoginRequiredMixin, CreateView):
model = Photo
fields = ['description', 'image', 'category']
template_name = 'post_create.html'
def form_valid(self, form):
form.instance.user = self.request.user
return super (PostCreativeView, self).form_valid(form)
#.......
# Models.py
class Photo(models.Model):
#>>>...
def __str__(self):
return str(self.category)
You should return the str(…) of the category, so:
class Photo(models.Model):
# …
def __str__(self):
return str(self.category)

'Account' object has no attribute 'products' AND (fields.E301) Field defines a relation with the model 'auth.User', which has been swapped out.'

I am following Django rest_framework tutorial to build my app but and I'm using a custom user model (Account) which inherits AbstractBaseUser.
I have another model - Product - and each product is owned by an Account.
My models.py is:
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.conf import settings
class Product(models.Model):
owner = models.ForeignKey(Account, related_name='account', on_delete=models.CASCADE, default=1)
name = models.CharField(max_length=71)
product = models.CharField(max_length=20, blank=True)
price = models.IntegerField(null=True, blank=True)
quantity = models.IntegerField(default=0)
image = models.ImageField(upload_to='images', blank=True)
display = models.BooleanField(default=False)
created = models.DateTimeField('date added', auto_now=True)
modified = models.DateTimeField('date modified', auto_now_add=True)
def __str__(self):
return self.name
class MyAccountManager(BaseUserManager):
def create_user(self, email, username, password=None):
if not email:
raise ValueError("Please enter a valid email address")
if not username:
raise ValueError("Please enter a username")
user = self.model(
email = self.normalize_email(email),
username = username,
)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
user = self.create_user(
email = self.normalize_email(email),
password = password,
username = username,
)
user.is_admin = True
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class Account(AbstractBaseUser):
email = models.EmailField(verbose_name='email', max_length=60, unique=True)
username = models.CharField(max_length=30, unique=True)
date_joined = models.DateTimeField(verbose_name='date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last_login', auto_now_add=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_merchant = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = MyAccountManager()
def __str__(self):
return self.email
def has_perm(self, perm, obj=None):
return self.is_admin
def has_module_perms(self, app_label):
return True
My settings.py includes:
AUTH_USER_MODEL = 'accounts.Account'
My serializers.py is:
from rest_framework import serializers
from inventory.models import Product
from accounts.models import Account
class AccountSerializer(serializers.ModelSerializer):
products = serializers.PrimaryKeyRelatedField(many=True, queryset=Product.objects.all())
password2 = serializers.CharField(style={'input_type': 'password'}, write_only=True)
class Meta:
model = Account
fields = ['products', 'email', 'username', 'password', 'password2']
extra_kwargs = {
'password': {'write_only': True}
}
def save(self):
account = Account(
email = self.validated_data['email'],
username = self.validated_data['username'],
)
password = self.validated_data['password']
password2 = self.validated_data['password2']
if password != password2:
raise serializers.ValidationError({'password': 'Passwordss must match.'})
account.set_password(password)
account.save()
return account
class ProductSerializer(serializers.ModelSerializer):
owner = serializers.ReadOnlyField(source='owner.email')
class Meta:
model = Product
fields = [
'id', 'owner', 'name', 'product', 'price', 'quantity', 'image', 'display'
]
My views.py is:
from accounts.api.serializers import AccountSerializer
from inventory.api.serializers import ProductSerializer
from inventory.models import Product
from accounts.models import Account
from rest_framework import permissions
from rest_framework import generics
class AccountList(generics.ListAPIView):
queryset = Account.objects.all()
serializer_class = AccountSerializer
class AccountDetail(generics.RetrieveAPIView):
queryset = Account.objects.all()
serializer_class = AccountSerializer
class ProductList(generics.ListCreateAPIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
queryset = Product.objects.all()
serializer_class = ProductSerializer
def perform_create(self, serializer):
serializer.save(owner=self.request.user)
class ProductDetail(generics.RetrieveUpdateDestroyAPIView):
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
queryset = Product.objects.all()
serializer_class = ProductSerializer
I am able to view my ProductList and ProductDetail however, I get the following error when I try to view AccountList and AccountDetail:
**Exception Type:** AttributeError
**Exception Value:** 'Account' object has no attribute 'products'
Just change your serailzier like this
class AccountSerializer(serializers.ModelSerializer):
products = serializers.SerializerMethodField()
password2 = serializers.CharField(style={'input_type': 'password'}, write_only=True)
def get_products(self, instance):
return Product.objects.all().values_list('id', flat=True)
class Meta:
model = Account
fields = ['products', 'email', 'username', 'password', 'password2']
extra_kwargs = {
'password': {'write_only': True}
}
def save(self):
account = Account(
email = self.validated_data['email'],
username = self.validated_data['username'],
)
password = self.validated_data['password']
password2 = self.validated_data['password2']
if password != password2:
raise serializers.ValidationError({'password': 'Passwordss must match.'})
account.set_password(password)
account.save()
return account
PrimaryKeyRelatedField may be used to represent the target of the relationship using its primary key. The queryset used for model instance lookups when validating the field input. Your field is read_only field. Your should use SerializerMethodField for this.

How can I access my models in django admin?

I am working on an AlumniTracker in django and till now I have created forms for user sign up and some additional information.
Even after saving the additional information form I am not able to access it in django-admin.
I am adding my models, views and forms file here.
views.py
def student_profile(request):
if request.method == 'POST':
form = StudentDetailForm(request.POST)
if form.is_valid:
student_form = form.save(commit=False)
student_form.user = request.user
student_form.save()
return redirect(reverse('homepage'))
else:
form = StudentDetailForm()
return render(request, 'authentication/student_profile.html', {'form':form})
def alumni_profile(request):
if request.method == 'POST':
form = AlumniDetailForm(request.POST)
if form.is_valid:
alumni_form = form.save(commit=False)
alumni_form.user = request.user
alumni_form.save()
return redirect(reverse('homepage'))
else:
form = AlumniDetailForm()
return render(request, 'authentication/student_profile.html', {'form':form})
forms.py
class StudentDetailForm(ModelForm):
class Meta:
model = StudentDetail
fields = ['first_name', 'last_name', 'contact_no', 'birth_date', 'course', 'session_start', 'session_end']
class AlumniDetailForm(ModelForm):
class Meta:
model = AlumniDetail
exclude = ['user']
models.py
class CustomUser(AbstractUser):
profile = models.CharField(max_length=10,choices=PROFILE_CHOICES, default='student')
def __str__(self):
return self.username
class StudentDetail(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
contact_no = models.IntegerField()
birth_date = models.DateField()
course = models.CharField(max_length=50)
session_start = models.IntegerField()
session_end = models.IntegerField()
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
class AlumniDetail(models.Model):
first_name = models.CharField(max_length=20)
last_name = models.CharField(max_length=20)
contact_no = models.IntegerField()
birth_date = models.DateField()
course = models.CharField(max_length=50)
session_start = models.IntegerField()
session_end = models.IntegerField()
company = models.CharField(max_length=60)
open and edit admin.py
and register your models by adding code below admin import
from .models import CustomUser,StudentDetail,AlumniDetail
admin.site.register(CustomUser)
admin.site.register(StudentDetail)
admin.site.register(AlumniDetail)

edit and update the row in database using django

models.py
class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()
age = models.IntegerField()
def __unicode__(self):
return "{0} {1} {2} {3} {4}".format(
self, self.first_name, self.last_name, self.email, self.age)
class Book(models.Model):
book_name=models.CharField(max_length=30)
publisher_name=models.CharField(max_length=40)
author=models.ForeignKey(Author)
def __unicode__(self):
return "{0} {1} {2}".format(
self.pk, self.book_name, self.publisher_name)
forms.py
class AuthorForm(ModelForm):
class Meta:
model = Author
BookFormset = inlineformset_factory(Author, Book,
fields=('book_name', 'publisher_name'), extra=1,
can_delete=False)
urls.py is
admin.autodiscover()
urlpatterns = patterns('',
url('^$', index),
url('^index/$', index),
url('^addbook/$', addbook),
url('^book_detail/$', book_detail, 'book_summary'),
url('^editbook/(?P<book_id>\d+)/$', editbook) ,
url('^deletebook/(?P<book_id>\d+)/$',deletebook) ,
url(r'^admin/', include(admin.site.urls)),
)
I need to perform edit and update the row in database,i did it by using single table.But using two table have some confusion how to take 2nd table using that particular id.I am using forms in this.Can you help me in this to write codes in views.py.Example for doing the same using two table is no where i seen.
Thanks
def update_book(request, book_id):
author = get_object_or_404(Author, pk=author_id)
form = AuthorForm(instance=author)
book_formset = BookFormset(instance=author)
if request.method == 'POST':
form = AuthorForm(request.POST, instance=author)
if form.is_valid():
author = form.save(commit=False)
book_formset = BookFormset(request.POST, instance=author)
if book_formset.is_valid():
author.save()
book_formset.save()
return redirect('/index/')
return render_to_response('updatebook.html',{
'form': form, 'formset': book_formset
},context_instance=RequestContext(request))
<div align="center">
<tr>
<form method="POST">
{% csrf_token %}
<h5>Author:</h5>
{{ form.as_p }}
<h5>Book:</h5>
{{ formset.as_p }}
<input type="submit" value="submit">
</form>
</tr>
</div>

Resources