use Manytomanyfield inputs in a model to create get_absolute_url - python

I have to create get_absolute_url from an input given into a manytomanyfield.
Here is the relevant model.
class ConnectTag(models.Models):
whitetags = models.ManyToManyField(Tag, related_name='whitectags')
name = models.CharField(max_length=20, blank=True)
user = models.ForeignField(User, related_name='directconnecttags')
detail = models.TextField(blank=True)
def get_absolute_url:
return "%s.%s.%s...." %tag1,%tag2 ,%tagn
where tag1,tag2,tag3 are whitetags. How do I rewrite the last line into actual code ?

Not entirely clear what you're asking, but this might help:
return '.'.join(self.whitetags.values_list('fieldname', flat=True))
where fieldname is the field name on the Tag model which you want to output.

Related

Insert multiple keywords in one field

My question is how i can insert multiple keywords in one django field and show them in a template like stackoverflow tags.
Models:
class Jobs(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(blank=True, default='')
company = models.ForeignKey(Company, on_delete=models.CASCADE)
tags = ?????
Create another class and use many-to-many relationship between jobs class (tags) and new class:
class Tags(models.Model):
tag_name=models.CharField()
In jobs class
tags=models.ManyToManyField(Tags)
For show in template you can use for loop, etc.
Make it a Comma separated value.
class Jobs(models.Model):
tags = models.TextField()
def tag_list(self):
return self.tags.split(",")
def add_tag(self, tag_str):
current_tags = self.tag_list()
current_tags.append(tag_str)
current_tags = set(current_tags)
new_tag_string = ",".join(current_tags)
self.tags = new_tag_string
# you could save the model now or let caller save it outside of this method. I suggest letting caller save the model.
def remove_tag(self, tag_str):
current_tags = self.tag_list()
current_tags.remove(tag_str)
new_tag_string = ",".join(current_tags)
self.tags = new_tag_string
# you could save the model now or let caller save it outside of this method. I suggest letting caller save the model.

Django Access to Foreign Key data to set a field default value

I have two models with their respective forms. One has a Foreign Key link to the other and from, here I would like to set some fields default data.
class Lexicon(models.Model):
[...]
case_sensitive = models.BooleanField(default=True)
invariant = models.NullBooleanField(default=False)
diacritics = models.BooleanField(default=True)
[...]
class Meta:
verbose_name = "lexicon"
ordering = ["filename"]
def __str__(self):
return self.filename
class Lexeme(models.Model):
lexicon = models.ForeignKey(Lexicon, on_delete=models.CASCADE)
case_sensitive = models.BooleanField(default=True)
diacritics = models.BooleanField(default=True)
[...]
class Meta:
verbose_name = "lexeme"
I would like the Lexeme model fields "case_sensitive" and "diacritics" to default from Lexicon. I suppose the forms may be a better place to do this.
Any idea ?
As I understand, you only need to populate data from Lexicon to Lexeme model fields. You can override get_form_kwargs in your FormView as follows
def get_form_kwargs(self):
lex_obj = Lexeme.objects.get(pk=self.kwargs['pk'])
kwargs = super().get_form_kwargs()
kwargs['initial']['case_sensitive'] = lex_obj.lexicon.case_sensitive
kwargs['initial']['diacritics'] = lex_obj.lexicon.diacritics
return kwargs
Is that what you want? I have not tested but, I have used similar thing on my project. Let me know if works or not.
I finally found the way to go. It was just basic initial setting of field, no need to touch to forms.py, models.py nor the html template.
I passed data to my form like this:
lexeme_form = LexemeForm(initial={'case_sensitive': lexicon.case_sensitive, 'diacritics': lexicon.diacritics})
use Ajax at template to change the initial value of "case_sensitive" and "diacritics" when Lexicon changed, and abstract model can be used to reduce repeat lines :
class BaseLex(models.Model):
case_sensitive = models.BooleanField(default=True)
diacritics = models.BooleanField(default=True)
class Meta:
abstract = True
class Lexicon(BaseLex):
# without `case_sensitive` and `diacritics' fields
...
class Lexeme(BaseLex):
# without `case_sensitive` and `diacritics' fields
lexicon = models.ForeignKey(Lexicon, on_delete=models.CASCADE)
...

DRF changing field name values of django models with foreign keys

I followed suggestion from this question
But i need to name one field of query_set to date filed of another object
My models are
class Choice(models.Model):
question = models.ForeignKey(Question, related_name='choice', on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
def __str__(self):
return self.choice_text
class ChoiceWithTime(models.Model):
choiceTime = models.ForeignKey(Choice,related_name='choiceTime', on_delete=models.CASCADE)
choice_date=models.DateField()
My view
class QuestionChoicesViewSet(viewsets.ModelViewSet):
queryset = Choice.objects.all()
serializer_class = ChoiceDateSerializer
def get_queryset(self):
return Choice.objects.values('choiceTime__choice_date','choice_text').annotate(
total_votes=Count('choiceTime__choice_date'),
)
I need to count number of submission in particular dates
I don't know how to name choiceTime__choice_date that serializer recognizes field in query set
class ChoiceDateSerializer(serializers.ModelSerializer):
choiceTime__choice_date = serializers.DateTimeField()
total_votes = serializers.IntegerField()
class Meta:
model = Choice
fields = ('id', 'choice_text','total_votes','choiceTime__choice_date')
i receive
{
"choice_text": "ant tower",
"total_votes": 3,
"choiceTime__choice_date": "2017-04-20"
}
But i want to recieve
{
"choice_text": "ant tower",
"total_votes": 3,
"choice_date": "2017-04-20"
}
Tried different options with no success. Definitely i am missing the point.
For my purposes it is working, but i want to have well written API.
2 option change time submission model?
class ChoiceWithTime(models.Model):
choiceTime = models.ForeignKey(Choice,related_name='choiceTime', on_delete=models.CASCADE)
choice_date=models.DateField()
coutner = models.IntegerField(default=0)
Is 2 option considers to be better approach to my particular problem? Thanks!
You are receiving a json object, which you add its key value.
for vote_detail in data:
if vote_detail.choiceTime__choice_date:
vote_detail.choice_date=vote_detail.choiceTime__choice_date
then serialize and save, a quick solution.
You could also add to your model the name that you want to call it. That's closer to backend and maybe worth delving into.
from django.db.models import Count,F
If anybody finds this problem and this is easiest answer i came up to.
As it was suggested before passing to serializer change value using model package functions
class QuestionChoicesViewSet(viewsets.ModelViewSet):
queryset = Choice.objects.all()
serializer_class = ChoiceDateSerializer
def get_queryset(self):
return Choice.objects.all().annotate(choice_date=F('choiceTime__choice_date')).values('choice_date','choice_text').annotate(
total_votes=Count('choiceTime__choice_date'),
)

Django Twitter clone. How to restrict user from liking a tweet more than once?

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}}

Django one-to-many relations in a template

I am searching of a method to obtain html forms from some one-to-many relations, like order-lineorder, invoice-lineinvoice, etc.
Let me an example:
# models.py
class Order(models.Model):
date = models.DateTimeField()
number = models.IntegerField(default=0)
class LineOrder(models.Model):
description = models.TextField()
price = models.FloatField()
order = models.ForeignKey(Order)
# views.py
def order_form(request):
form = OrderForm()
table_lineorder = LineOrderTable([])
RequestConfig(request).configure(table)
return render(request, "order_form.html", {"form": form, "table": table_lineorder})
Then, I want to obtain the order template with "generic attributes" (date, number), and a table list (originally empty) of lines order. Add some action like add, edit and remove must be possible.
I think that a solution like django-tables2 is possible, but I can't add rows dinamically, I think.
Thanks in advice.
[EDIT]
I have found the solution. It is django-dynamic-formset
I'm not quite clear about your question, but I guess this might be what you want:
class Order(models.Model):
date = models.DateTimeField()
number = models.IntegerField(default=0)
items = model.ManyToManyField(Item)
class Item(models.Model):
description = models.TextField()
price = models.FloatField()
It should be equivalent to one-to-many if you don't assign one Item to multiple Orders.

Categories

Resources