Strange error. When I am trying to add some data to my charfield it shows me error like this: invalid literal for int() with base 10:
Here is my models:
class Follower(models.Model):
follower = models.CharField(max_length=140)
def __unicode__(self):
return self.follower
class Following(models.Model):
following = models.CharField(max_length=140)
def __unicode__(self):
return self.following
class UserProfile(models.Model):
# This line is required. Links UserProfile to a User model instance.
user = models.OneToOneField(User)
# The additional attributes we wish to include.
website = models.URLField()
followers = models.ManyToManyField(Follower)
following = models.ManyToManyField(Following)
Views:
if request.GET.get('follow'):
author = UserProfile.objects.get(user__username__iexact=username)
b = "AAA"
author.followers.add(b)
What to do?
followers is not a CharField, it is a ManyToManyField. You can't just add text to it: you need to create an instance of Follower, or get an existing one, and add it.
Related
I have the following Models:
class Book(models.Model):
name = models.CharField(max_length=128)
isbn = models.CharField(max_length=13, unique=True)
available = models.BooleanField(default=True)
class Borrow(models.Model):
date = models.DateTimeField(auto_now_add=True)
book = models.ForeignKey(Book)
and the following ModelForm:
class CreateBorrowForm(forms.ModelForm):
class Meta:
model = Borrow
fields = ['book']
def clean_book(self):
book = self.cleaned_data['book']
try:
return Book.objects.get(id=book, available=True)
except Book.DoesNotExist:
raise ValidationError('Book does not exist or it is unavailable')
I would like to have a form that expects the isbn field of the Book model, instead of id. As the isbn field is unique, it does make sense. In the clean_book method I would need to do a little change to have the following line:
return Book.objects.get(isbn=book, available=True)
The problem is that I cannot find an approach to force the form to use a different unique identifier. In my specific case, this is required to avoid brute force enumerating over numerical IDs.
You'd need to use a custom field for that, and override the save() method instead of the clean__field():
class CreateBorrowForm(forms.ModelForm):
book_isbn = forms.CharField()
class Meta:
model = Borrow
fields = ['book_isbn']
def save(self, commit=True):
instance = super().save(commit=False)
book_isbn = self.cleaned_data['book_isbn']
try:
book = Book.objects.get(isbn=book_isbn, available=True)
instance.book = book
except Book.DoesNotExist:
raise ValidationError('Book does not exist or it is unavailable')
if commit:
instance.save()
return instance
I am having problems filtering options for a ManyToManyField on the Django Admin Add screen based on input to another field on the same form. I am new to Django and have been unable to use any of the generic fixes described elsewhere because they are all slightly different than my situation. Here is my situation:
I have three models in my project: Class, Student, and AttendanceRecord. In the Django Admin, when adding an attendance record, I would like to change the options for the field Absent_Students based on the selection made for the field Associated_Class. So, for example, if Associated_Class "CS 450" is selected, the options for Absent_Students should change to only students whose class_list includes CS 450.
Here are my models:
from __future__ import unicode_literals
from django.db import models
from django.contrib.auth.models import User
from django.utils.encoding import python_2_unicode_compatible
import random, string
# Create your models here.
#This is the model for a student
#python_2_unicode_compatible
class Student(models.Model):
pass
Student_First_Name = models.CharField(max_length=200)
Student_Last_Name = models.CharField(max_length=200)
Student_ID_Number = models.CharField(max_length=200)
Student_Class = models.ForeignKey('Class', null=True)
def __str__(self):
return self.Student_Last_Name + ',' + self.Student_First_Name
# This is the model for a class
#python_2_unicode_compatible
class Class(models.Model):
class Meta:
verbose_name_plural = "Classes"
Class_Name = models.CharField(max_length=200)
Student_List = models.ManyToManyField('Student', related_name='class_list')
Professor = models.ForeignKey(User,null=True)
AddCode = models.IntegerField
pass
def __str__(self):
return self.Class_Name
def getName(self):
return self.Class_Name
def getProfessor(self):
return self.Professor.id
def getProf(self):
return self.Professor
def getStudents(self):
return self.Student_List
#This is the model for attendance records
class AttendanceRecord(models.Model):
class Meta:
verbose_name = "Attendance Record"
Associated_Class = models.ForeignKey(Class, on_delete=models.CASCADE, related_name='Attendance_Records')
Date = models.DateField()
Absent_Students = models.ManyToManyField('Student', blank=True)
Present_Students = models.ManyToManyField('Student', related_name='a')
def get_associated_class_id(self):
return self.Associated_Class
def __str__(self):
return self.Associated_Class.__str__() + ' on date ' + self.Date.__str__(self)
I have tried doing this by editing the AttendanceRecordAdminForm class and AttendanceRecordAdmin class. My problem is that when setting the self.fields['Absent_Students].queryset I do not know how to access the currently selected Associated_Class on the form. I keep getting an error that "AttendanceRecord has no Associated_Class". Here are those classes just discussed in their entirety:
class AttendanceRecordAdminForm(forms.ModelForm):
class Meta:
model = AttendanceRecord
fields = '__all__'
def __init__(self, *args, **kwargs):
super(AttendanceRecordAdminForm, self).__init__(*args, **kwargs)
instance = kwargs.get('instance', None)
self.fields['Absent_Students'].queryset = Student.objects.filter(class_list__id=self.instance.get_associated_class_id())
self.fields['Present_Students'].queryset = Student.objects.filter(class_list__id=1)
class AttendanceRecordAdmin(admin.ModelAdmin):
form = AttendanceRecordAdminForm
filter_horizontal = ('Absent_Students', 'Present_Students',)
Basically, I am looking for a way to access the currently entered Associated_Class on the admin form so I can properly filter the queryset.
After hours more of online searching I finally found what I needed. A chained ManyToMany from the smart_select app makes this very easy. This link: How to use django-smart-select describes the install process and also links to the documentation for using it once it is installed. Hopefully this helps some others as well.
I'm not sure where to start. Right now, the user can press like as many times they want and it'll just add up the total likes for that tweet.
models.py
class Howl(models.Model):
author = models.ForeignKey(User, null=True)
content = models.CharField(max_length=150)
published_date = models.DateTimeField(default=timezone.now)
like_count = models.IntegerField(default=0)
rehowl_count = models.IntegerField(default=0)
def get_absolute_url(self):
return reverse('howl:index')
def __str__(self):
return self.content
views.py
class HowlLike(UpdateView):
model = Howl
fields = []
def form_valid(self, form):
instance = form.save(commit=False)
instance.like_count += 1
instance.save()
return redirect('howl:index')
Django Twitter clone. How to restrict user from liking a tweet more than once?
As well as tracking how many Likes a post has, you'll probably also want to track who has "Liked" each post. You can solve both of these problems by creating a joining table Likes with a unique key on User and Howl.
The unique key will prevent any User from doing duplicate likes.
You can do this in Django with a ManyToManyField, note that since this means adding a second User relationship to Howl, we need to disambiguate the relationship by providing a related_name
Eg:
class Howl(models.Model):
author = models.ForeignKey(User, null=True, related_name='howls_authored')
liked_by = models.ManyToManyField(User, through='Like')
# ...rest of class as above
class Like(models.Model):
user = models.ForeignKey(User)
howl = models.ForeignKey(Howl)
class Meta:
unique_together = (('user', 'howl'))
like_count count then becomes redundant, since you can use Howl.liked_by.count() instead.
The other benefit of this is that it allows you to store information about the Like - eg when it was added.
An idea could be adding a column to your table named likers and before incrementing like_counts check if the models.likers contains the new liker or not. If not increment the likes, if yes don't.
Changed liked_count in my models.py to
liked_by = models.ManyToManyField(User, related_name="likes")
views.py
class HowlLike(UpdateView):
model = Howl
fields = []
def form_valid(self, form):
instance = form.save(commit=False)
instance.liked_by.add(self.request.user)
instance.like_count = instance.liked_by.count()
instance.save()
return redirect('howl:index')
index.html
{{howl.liked_by.count}}
I am trying to get the user from a model into a view, however I keep getting a type error:
Type error - int() argument must be a string or a number, not 'ReverseSingleRelatedObjectDescriptor'
When I get to the user I have the following:
django.db.models.fields.related.ReverseSingleRelatedObjectDescriptor object at 0x7f4a15299590
Models.py
#python_2_unicode_compatible
class SocialAccount(models.Model):
user = models.ForeignKey(allauth.app_settings.USER_MODEL)
provider = models.CharField(verbose_name=_('provider'),
max_length=30,
choices=providers.registry.as_choices())
uid = models.CharField(verbose_name=_('uid'),
max_length=app_settings.UID_MAX_LENGTH)
last_login = models.DateTimeField(verbose_name=_('last login'),
auto_now=True)
date_joined = models.DateTimeField(verbose_name=_('date joined'),
auto_now_add=True)
extra_data = JSONField(verbose_name=_('extra data'), default='{}')
class Meta:
unique_together = ('provider', 'uid')
verbose_name = _('social account')
verbose_name_plural = _('social accounts')
def authenticate(self):
return authenticate(account=self)
def __str__(self):
return force_text(self.user)
Views.py
from allauth.socialaccount.models import SocialToken, SocialAccount
def sc(request):
user = SocialAccount.user
token = SocialToken.objects.filter(account__user=user, account__provider='soundcloud')
In your view, SocialAccount is the model itself, not a particular instance of it. You would need to actually query for the account you want, like you do with the token.
But I'm not sure why you are doing anything with SocialAccount in the first place. You actually want the user, which is presumably just request.user; use that instead.
I need have a search box, one of fields of the model has a M2M field. I got to put it works but only works when i look for the id of the M2M field, not for the name. my models:
class Specialities(models.Model):
name = models.CharField(max_length=100)
def __str__(self):
return self.name
class Profile(models.Model):
user = models.OneToOneField(User)
name = models.CharField(max_length=200)
specialities = models.ManyToManyField(Specialities)
def __str__(self):
return self.name
And my view:
class SearchView(TemplateView):
template_name = 'contadores/search.html'
def post(self,request,*args,**kwargs):
buscar = request.POST['buscar']
contadores = Profile.objects.filter(specialities=buscar)
ctx = {'contadores':contadores}
return render_to_response('contadores/resultados.html',ctx,context_instance=RequestContext(request))
The queryset in "contadores" works fine, but as i told before, the search box only receive the id of the M2M field, if i look for the word in the search box django says: invalid literal for int() with base 10: 'niif' I know the reason, but how can i pass to the search box the word of the M2M field associated to the Specialities model instead the id?
What you can do is search by related table, like this:
contadores = Profile.objects.filter(specialities__name__iexact = request.POST['buscar'])
Try like this:
buscar = Specialities.objects.filter(name__iexact = request.POST['buscar'])
if buscar.exists():
contadores = Profile.objects.filter(specialities=buscar[0])