Correct if/else statement syntax for django templates

有些话、适合烂在心里 提交于 2021-01-29 04:49:46

问题


I have a dating app and I need to create a link that is underneath each profile that a user matches on. Then, that link should pass their user id into the template so that messages are only displayed between the current user and that particular user based on the user id. I am having trouble here with the syntax of if/else statements within the Django template. How would I go about doing this?

**base.html/href messages link **

<li class="nav-item">
                    <a class="nav-link" href="{% url 'dating_app:messages' user.id %}">Check Messages</a>
                </li>

models.py/InstantMessage

class InstantMessage(models.Model):

    sender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name= 'sender',on_delete=models.CASCADE )
    receiver = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    message = models.TextField()
    date = models.DateTimeField(auto_now_add=True)


    def __unicode__(self):
        return self.message

messages.html

<div id="msg-list-div" class="panel-body">
        <ul id="msg-list" class="list-group">
            <br><br><br>
            {% for obj in messages %}
                {% if obj.sender == request.user and obj.receiver == profile%}

                    {% if obj.sender == request.user%}
                        <li class="text-right list-group-item">{{obj.message}}<br>{{ obj.date }}<li>
                    {% elif obj.receiver == profile %}
                        <li class="text-left list-group-item">{{obj.message}}<br>{{ obj.date }}<li>
                    {%endif%} 

                {%endif%}   
                {% empty %}
                    <li class="text-right list-group-item">No messages yet...Keep mingling!</li>
            {% endfor %}

        </ul>
</div>

matches.html/ href link for messages.html

<p><a href="{% url 'dating_app:messages' profile.id %}">chat</a></p>

views.py/messages

def messages(request, profile_id):
    messages = InstantMessage.objects.all()
    profile = get_object_or_404(Profile,id=profile_id)

    return render(request, 'dating_app/messages.html', {'messages': messages,'profile':profile,})

models.py

class Profile(AbstractBaseUser):

    class Meta:
        swappable = 'AUTH_USER_MODEL'


    email                       = models.EmailField(verbose_name="email")
    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=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)
    #what I added
    description                 = models.TextField()
    photo                       = models.ImageField(upload_to='profile_photo',blank=False, height_field=None, width_field=None, max_length=100)
    matches                     = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='+', blank=True)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['description','photo','email']

    objects = ProfileManager()

    def __str__(self):
        return self.username

    def has_perm(self, perm, obj=None):
        return self.is_admin

    def has_module_perms(self,app_label):
        return True


class UserVote(models.Model):

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    voter = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='given_vote', on_delete=models.CASCADE)
    vote = models.BooleanField(default=False)

    class Meta:
        unique_together = (('user', 'voter'))


class InstantMessage(models.Model):

    sender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name= 'sender',on_delete=models.CASCADE )
    receiver = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    message = models.TextField()
    date = models.DateTimeField(auto_now_add=True)


    def __unicode__(self):
        return self.message

entire models.py

from django.db import models
from django.contrib.auth.models import AbstractBaseUser,BaseUserManager, User
from dating_project import settings
from django.contrib.auth import get_user_model


class ProfileManager(BaseUserManager):



    def create_user(self, username, email,description,photo, password=None):
        if not email:
            raise ValueError("You must creat an email")
        if not username:
            raise ValueError("You must create a username!")
        if not description:
            raise ValueError("You must write a description")
        if not photo:
            raise ValueError("You must upload a photo")

        user = self.model(
                email=self.normalize_email(email),
                username = username, 
                description= description,
                photo= photo,

            )

        user.set_password(password)
        user.save(using=self._db)
        return user 


    def create_superuser(self, username, email,description,photo, password):
        user = self.create_user(
                email=self.normalize_email(email),
                password=password,
                username=username,
                description=description,
                photo=photo,

            )

        user.is_admin=True
        user.is_staff=True
        user.is_superuser=True
        user.save(using=self._db)
        return user




class Profile(AbstractBaseUser):

    class Meta:
        swappable = 'AUTH_USER_MODEL'


    email                       = models.EmailField(verbose_name="email")
    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=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)
    #what I added
    description                 = models.TextField()
    photo                       = models.ImageField(upload_to='profile_photo',blank=False, height_field=None, width_field=None, max_length=100)
    matches                     = models.ManyToManyField(settings.AUTH_USER_MODEL, related_name='+', blank=True)



    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['description','photo','email']


    objects = ProfileManager()


    def __str__(self):
        return self.username


    def has_perm(self, perm, obj=None):
        return self.is_admin


    def has_module_perms(self,app_label):
        return True



class UserVote(models.Model):

    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    voter = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='given_vote', on_delete=models.CASCADE)
    vote = models.BooleanField(default=False)

    class Meta:
        unique_together = (('user', 'voter'))



class InstantMessage(models.Model):

    sender = models.ForeignKey(settings.AUTH_USER_MODEL, related_name= 'senderr',on_delete=models.CASCADE )
    receiver = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
    message = models.TextField()
    date = models.DateTimeField(auto_now_add=True)


    def __unicode__(self):
        return self.message

回答1:


As already suggested it is better to do all heavy work in a view, not in a template:

def messages(request, profile_id):
    messages = InstantMessage.objects.filter(sender=request.user, receiver_id=profile_id, )
    profile = get_object_or_404(Profile,id=profile_id)
    ...

Imagine if InstantMessage contains billions of records - how fast would InstantMessage.objects.all() work? And for what reason.

And since you want to render "a chat", I guess you need something like this:

from django.db.models import Q
...
    messages = InstantMessage.objects.filter(Q(sender_id=request.user.id, receiver_id=profile_id,) 
            | Q(sender_id=profile_id, receiver_id=request.user.id,) ).\
        values('sender_id', 'message', 'date', ).\
        order_by('date',)

see also examples of making complex queries in the docs.

and the template:

{% for msg in messages %}
    <li class="{% if msg.sender_id == request.user.id %}text-right{% else %}text-left{% endif %} list-group-item">
        {{ msg.message }}<br/>{{ msg.date }}
    </li>
{% empty %}
    ...
{% endfor %}


来源:https://stackoverflow.com/questions/61150352/correct-if-else-statement-syntax-for-django-templates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!